题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路
O(n)时间算法,只有可以修改输入数组时可用。
可以基于 Partition 函数来解决这个问题。如果基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数组的左边,比第 k 个数字大的所有数字都位于数组的右边。这样调整之后,位于数组中左边的 k 个数字就是最小的 k 个数字(这 k 个数字不一定是排序的)。
import java.util.ArrayList; public class Test { public static void main(String[] args) { int[] a = { 4, 5, 1, 6, 2, 7, 3, 8}; System.out.println(GetLeastNumbers_Solution(a, 8)); } public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) { ArrayList<Integer> list = new ArrayList<Integer>(); if(input == null || input.length <= 0 || k > input.length || k <= 0) return list; int index = partition(input, 0, input.length - 1); while (index != k - 1) { if(index > k - 1) index = partition(input, 0, index - 1); else index = partition(input, index + 1, input.length - 1); } for(int i=0; i<k; i++) { list.add(input[i]); } return list; } private static int partition(int[] input, int low, int high) { if(input == null || input.length <= 0 || low < 0 || high >= input.length || low > high ) return 0; int key = input[low]; while(low < high) { while(low < high && input[high] >= key) high --; input[low] = input[high]; while(low < high && input[low] <= key) low ++; input[high] = input[low]; } input[low] = key; return low; } }