输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
package cn.com.jianzhioffer;
import java.util.ArrayList;
public class Solution30 {
// public ArrayList<Integer> GetLeastNumbers_Solution(int[] input,int k){
// ArrayList<Integer> list = new ArrayList<Integer>();
// if(input==null||k>input.length) return list;
// for(int i = 0;i<k;i++){
// for(int j=i;j<input.length;j++){
// if(input[i]>input[j]){
// int t = input[i];
// input[i] = input[j];
// input[j] = t;
// }
// }
// list.add(input[i]);
// }
// return list;
// }
/*
* 方法一:o(n),此时要求可以修改数组
* 基于Partition函数来解决
* 如果基于数组的第k个数字来调整,使比第k个数字小的所有数字都位于数组的左边,
* 比第k个数字大的所有数字都位于数组的右边
* 这样之后,位于数组中左边的k个数字就是最小的k个数字(这k个数字不一定有序)
*/
public ArrayList<Integer> GetLeastNumbers(int[] input,int k){
ArrayList<Integer> list = new ArrayList<Integer>();
int length = input.length;
if(input==null||length<=0||k>length||k<=0) return list;
int start = 0;
int end = 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;
}
//一次快排
public int Partition(int[] input,int start,int end){
int i = start;
int j = end;
int key = input[i];
while(i<j){
//按j--方向遍历目标数组,直到比key小的值为止
while(i<j&&key<=input[j]){
j--;
}
if(i<j){
//input[i]已经保存在key中,可以将后面的数填入
input[i] = input[j];
i++;
}
//按i++方向遍历数组,直至比key大的值为止
while(i<j&&input[i]<=key){
i++;
}
if(i<j){
//input[j]已经保存在input[i],可将前面的值填入
input[j] = input[i];
j--;
}
}
//此时i==j
input[i] = key;
return i;
}
}