今日心情:感觉做过的题还是不会 😮💨😮💨
题目描述:
输入整数数组
arr
,找出其中最小的k
个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
解题代码:
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
process(arr,0,arr.length-1);
int[] res = new int[k];
for(int i = 0; i < k ; i++){
res[i] = arr[i];
}
return res;
}
public void process(int[] arr, int L, int R){
if(L >= R){return;}
int[] equalRange = partition(arr,L,R);
process(arr,L,equalRange[0]-1);
process(arr,equalRange[1]+1,R);
}
public int[] partition(int[] arr, int L, int R){
int index = L;
int lessR = L-1;
int moreR = R;
while(index < moreR){
if(arr[index] < arr[R]){
swap(arr,++lessR,index++);
}else if(arr[index] > arr[R]){
swap(arr,--moreR,index);
}else{
index++;
}
}
swap(arr,moreR,R);
return new int[]{lessR+1,moreR};
}
public void swap(int[] arr, int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
解题思路:
采用快排对整个数组进行升序排序
(1)将整个数组按照最后一个数据进行大小划分,大的放在右边,小的放在左边。
-- 设置范围L 左边起始位置, R右边终点位置,lessR = L-1 小于最后一个数的指标,moreR =R 大于最后一个数的指标。
-- 从 index = L 开始,以数组最后一个数为判断标准,如果当前index所指的数小于最后一个数,将,lessR加一,与index位置的数进行互换,实际上该数位置不变,然后index加1. 如果当前index所指的数大于最后一个数,此时moreR减1,index不变,对两个位置上的数进行交换。如果相等则index加1,移动index继续判断下一个数。
-- 当 index == moreR 的时候,说明所有交换完成,退出循环。注意此时最后一个数需要和moreR换位置。
-- 返回 lessR+1 和 moreR 值,进行下一次递归的范围判断。
public int[] partition(int[] arr, int L, int R){
int index = L;
int lessR = L-1;
int moreR = R;
while(index < moreR){
if(arr[index] < arr[R]){
swap(arr,++lessR,index++);
}else if(arr[index] > arr[R]){
swap(arr,--moreR,index);
}else{
index++;
}
}
swap(arr,moreR,R);
return new int[]{lessR+1,moreR};
}
交换函数
public void swap(int[] arr, int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
(2)递归函数:(对不等于最后一个数的左右两段进行排序,递归实现整个数组的升序排序)
-- 退出递归条件:L与R边界撞上的时候
-- 获取左右边界范围(equalRange[0] 是 lessR+1 ,即等于最后一个数的第一个下标范围,equalRange[1] 是moreR , 即等于最后一个数的最后一个下标范围)
-- 对于不等于最后一个数的左右范围进行递归
递归的左边范围: L 到 equalRange[0]-1
递归的右边范围 :equalRange[1]+1 到 R
public void process(int[] arr, int L, int R){
if(L >= R){return;}
int[] equalRange = partition(arr,L,R);
process(arr,L,equalRange[0]-1);
process(arr,equalRange[1]+1,R);
}
(3)调用递归函数对数组进行升序排序,然后输出前k个数,即为当前数组中前k个最小的值