又到了金三银四找实习,找工作的时机,兄弟们都拿到自己心仪的offer了吗?下面我来分享一下面试过程中,出现频率非常高的面试题之一的-------剑指 Offer 40. 最小的k个数
一:题目背景:
二:分析:
拿到题目,小伙伴迫不及待的想试一试,心想这么简单的题还需要做吗?于是直接采用Arrays.sort(arr),再来一个循环遍历,遍历k个数字即可,完美结束。面试官:回去等待通知。然后就没有然后了。
仔细想一想,它考察的目的到底是什么?肯定不是你对库函数调用的熟练度。本道题目,确实基于排序来实现的,那么总多的排序该采用哪一种呢?冒泡,插入,选择,归并,快速,希尔等等。再来仔细分析一下,我们只需要拿到前k个有序的数字就行,剩余的数字不用管。是不是快速排序非常合适,为什么说合适呢?想一想快速排序的原理?是不是每次选出一个哨兵节点,对数组中的数字来判断,小于等于的移动到哨兵左边,大于等于的移动到右边,我们最后判断哨兵位置下标,如果下标小于k,说明需要继续要向有遍历,同样大于k,向左进行遍历,直到等于k时,我们直接返回K左边的数组即可。
三:代码实现:
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if(arr.length <= k) return arr;
return QuickSort(arr,0,arr.length - 1,k);
}
public int[] QuickSort(int[] arr,int i,int j,int k) {
int left = i,right = j,index = arr[i];
while(left < right) {
while(right > left && arr[right] >= index) {
right--;
}
while(right > left && arr[left] <= index) {
left++;
}
if(left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
int t = arr[left];
arr[left] = index;
arr[i] = t;
if(left < k) QuickSort(arr,right + 1,j,k);
if(left > k) QuickSort(arr,i,left - 1,k);
return Arrays.copyOf(arr,k);
}
}