剑指offer_最小k个数(java)
题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,
思路解析
使用partition()方法,基于数组第k个数调整,使得比k小的数字都位于其左边
注释有详细解析
java代码
import java.util.ArrayList;
/*输入n个整数,找出其中最小的K个数。
例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。*/
public class Solution_KLeastNumbers {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
//根据方法返回类型,定义返回对象
ArrayList<Integer> KLeast = new ArrayList<Integer>();
//数组为空,或者k小于等于0,或者k超过了数组长度,直接返回空的ArrayList
if (input == null || k <= 0 || k > input.length)
return KLeast;
int left = 0;
int right = input.length - 1;
//获取partition()方法返回的值(第left个的下标left)
int index = partition(input, left, right);
//循环退出条件,排好了第k-1个,因为从第0个开始,即已经排好前k个
while (index != k - 1) {
if (index < k - 1) {
left = index + 1;
//从下一个开始继续比较交换
index = partition(input,left,right);
} else {
right = index - 1;
index = partition(input,left,right);
}
}
//输出前k个数
for(int i = 0;i < k; i++)
KLeast.add(input[i]);
return KLeast;
}
private int partition(int[] arr,int left,int right){
int tempkey = arr[left];
int temp;
while(left < right){ //递归出口
//从右往左扫描,当右边比tempkey大,继续往左比较(right--),直到找到第一个比它tempkey的(while退出)
while(left < right && arr[right] >= tempkey)
right--;
//交换
temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
//从左往右扫描,当左边比tempkey小,继续往右比较(left++),直到找到第一个比tempkey大的(while退出)
while(left < right && arr[left] <= tempkey)
left++;
//交换
temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
//返回目前已经排好的第left个的下标
return left;
}
}