问题描述:
输入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
来源:oschina
链接:https://my.oschina.net/u/2356166/blog/524815