IT公司100题-5-查找最小的k个元素

北慕城南 提交于 2020-02-29 06:04:10

问题描述:

输入n 个整数,输出其中最小的k 个。

例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1。


问题分析:

时间复杂度O(nlogn)方法:

对n个整数升序排序,取数组前面k个数就是最小的k个数,时间复杂度为O(nlogn),空间复杂度为O(1)。

大顶堆,时间复杂度为O(nlogk):

我们可以采用大顶堆来保存最小的k个数,堆顶元素就是k个最小的数中最大的。新来一个元素的时候,与堆顶元素进行比较,如果比堆顶元素大,则直接丢弃。如果比堆顶元素小,则替换堆顶元素,并且进行大顶推的调整,需要O(logk)的时间。所以总的时间复杂度为O(nlogk),空间复杂度为O(k)。

TreeSet时间复杂度为O(nlogk):

TreeSet容器的内部结构通常由红黑树来实现,所以查找、删除和插入操作都只需要O(logk)的时间。


代码实现:

package oschina.IT100;
/**
 * @project: oschina
 * @filename: IT5.java
 * @version: 0.10
 * @author: JM Han
 * @date: 10:52 2015/11/2
 * @comment: 输入n 个整数,输出其中最小的k 个。
 * @comment: 例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1。
 * @result:
 */

import java.util.*;
import static tool.util.*;

public class IT5 {
   public static final int NUM = 3;
   public static void find3least(List<Integer> lst){
      TreeSet<Integer> innerlst = new TreeSet<Integer>();
      for (int i = 0; i < lst.size(); i++) {
         int x = lst.get(i);
         if(innerlst.size() < NUM) {
            innerlst.add(x);
         } else {
            int max = innerlst.last();
            if(x < max){
               innerlst.add(x);
               innerlst.remove(max);
            }
         }
      }
      if(innerlst.size() != 0){
         printGenericIterator(innerlst.iterator());
      }
   }

   public static void main(String[] args) {
      Integer[] testArray = new Integer[]{8, 7, 6, 5, 4, 3, 2, 1};
      List<Integer> lst = Arrays.asList(testArray);
      Integer[] arra = lst.toArray(new Integer[0]);
      for(Integer i:arra)
         System.out.print(i+" ");
      System.out.println();
      find3least(lst);
   }
}

代码输出:

8 7 6 5 4 3 2 1 
1 2 3


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!