问题描述:
输入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.mianshi; /** * @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 boolean sorted = false; 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); find3least(lst); } }
代码输出:
1 2 3