《软件工程师面试题精选》06.查找最小的k个元素

《程序员面试题精选》06.查找最小的k个元素

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

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


分析:首先我们会简单想到将所有元素都排序,然后取出最小的几个,但是当数据量大的时候呢,这种方法显然不行。那么我们就把范围缩小,我们的目的就是那最小的k个数,那么我们就用一个单独的容器来存储这k个数,然后当插入下一个数之前先判断一下插入数与容器中最大数的大小关系,如果大于最大数则,容器内的数不变,如果小了,则删除容器中的最大数,插入这个数。那么这个容易应该是怎样的呢,显然他是要有序的,因为每次插入数的时候我们都要知道他的最大数,这里我们会想到用红黑树(既能保证有序,又能保证最坏情况不会成为链表,详见Red-Black Trees(红黑树))。因为二叉树的操作时间复杂度为O(logk),所以时间复杂度为O(nlogK).

在java中TreeSet实现了红黑树数据结构,所以我们下面就利用它来写这个程序。当然你也可以自己去实现,不过代码会很多。如果你想自己实现,可以看文章最后面我推荐的两篇博客,里面有详细介绍红黑树的实现。

import java.util.* ;
public class GetLeastNum{

	public static TreeSet<Integer> getLeastNum(int a[],int k){
		TreeSet<Integer> set = new TreeSet<Integer>() ;
		if(a.length>k||k<=0){
			System.out.println("error") ;
		}
		for(int i=0 ;i<a.length;i++){
			if(set.size()<k){
				set.add(a[i]) ;
			}else{
				if(a[i]<set.last()){
					set.remove(set.last()) ;
					set.add(a[i]) ;
				}
			}
		}
		return set ;
	}

	public static void main(String args[]){
		int a[] = {12,52,37,34,29,61,23} ;
		Iterator<Integer> it =  getLeastNum(a,4).iterator();
		while(it.hasNext()){
			System.out.println(it.next()) ;    //print:12 23 29 34
		}
	}
}


相关推荐:

  • java集合类TreeMap和TreeSet
  • Red-Black Trees(红黑树)