题目描述
- 输入n个整数,找出其中最小的K个数。
- 例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
解法1
- 对数组排序,取前边k个数存到list集合中
- 该解法时间复杂度依赖于排序
代码实现
public ArrayList<Integer> getLeastNumbers(int [] input, int k) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(input == null || input.length == 0 || input.length < k || k <= 0){
return list;
}
Arrays.sort(input);
for(int i = 0; i < k; i++){
list.add(input[i]);
}
return list;
}
解法2
- 基于partition函数
- 只有当我们可以修改输入的数组时可用
代码实现
public ArrayList<Integer> GetLeastNumbers_Solution2(int [] input, int k) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(input == null || input.length == 0 || input.length < k || k <= 0){
return list;
}
int start = 0;
int end = input.length - 1;
int index = partition(input, start, end);
while(index != k - 1){
if(index > k - 1){
end = index - 1;
index = partition(input, start, end);
}else{
start = index + 1;
index = partition(input, start, end);
}
}
for(int i = 0; i < k; i++){
list.add(input[i]);
}
return list;
}
private int partition(int[] input, int low, int high) {
int pivotKey = input[low];
while(low < high){
while(low < high && input[high] >= pivotKey){
high--;
}
input[low] = input[high];
while(low < high && input[low] <= pivotKey){
low++;
}
input[high] = input[low];
}
input[low] = pivotKey;
return low;
}
解法3
- 适合海量数据的处理
- 创建一个用于保存最小k个数的容器
- 第一步是放入k个元素,
- 第二步是比较容器中最大的数与当前数组遍历的那个数的大小
- 如果容器中最大的数比当前遍历的数大,就移除该数,并放入当前遍历的那个数
- 最大堆或红黑树都能实现这样的容器
代码实现
public ArrayList<Integer> GetLeastNumbers_Solution3(int[] input, int k) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(input == null || input.length == 0 || input.length < k || k <= 0){
return list;
}
TreeSet<Integer> s = new TreeSet<Integer>();
for(int i = 0; i < input.length; i++){
if(s.size() < k){
s.add(input[i]);
}else{
if(input[i] < s.last()){
s.remove(s.last());
s.add(input[i]);
}
}
}
Iterator<Integer> it = s.iterator();
while(it.hasNext()){
list.add(it.next());
}
return list;
}