剑指 Offer 40. 最小的k个数
难度:简单
输入整数数组 arr
,找出其中最小的 k
个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
示例 2:
输入:arr = [0,1,2,1], k = 1
输出:[0]
限制:
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000
解答:
class Solution {
//小顶堆
//时间复杂度O(NlogN)。空间复杂度:O(N)
public int[] getLeastNumbers(int[] arr, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
for(int num : arr){
pq.offer(num);
}
int[] ans = new int[k];
for(int i = 0; i < k; i++){
ans[i] = pq.poll();
}
return ans;
}
}
class Solution {
//先排序,然后将前k个输出
//时间复杂度O(NlogN)。空间复杂度:O(logN)
public int[] getLeastNumbers(int[] arr, int k) {
int[] ans = new int[k];
Arrays.sort(arr);
for(int i = 0; i < k; i++){
ans[i] = arr[i];
}
return ans;
}
}
class Solution {
//借鉴快排的思想
//时间复杂度期望O(N),最坏是O(N2)。空间复杂度:O(logN)
public int[] getLeastNumbers(int[] arr, int k) {
randomizedSelected(arr, 0, arr.length - 1, k);
int[] vec = new int[k];
for(int i = 0; i < k; i++){
vec[i] = arr[i];
}
return vec;
}
private void randomizedSelected(int[] arr, int l, int r, int k){
if(l >= r){
return;
}
int pos = randomizedPartition(arr, l, r);
int num = pos - l + 1;
if(k == num){
return;
}else if(k < num){
randomizedSelected(arr, l, pos - 1, k);
}else{
randomizedSelected(arr, pos + 1, r, k - num);
}
}
private int randomizedPartition(int[] nums, int l, int r){
int i = new Random().nextInt(r - l + 1) + l;
swap(nums, r, i);
return partition(nums, l, r);
}
private int partition(int[] nums, int l, int r) {
int pivot = nums[r];
int i = l - 1;
for (int j = l; j <= r - 1; ++j) {
if (nums[j] <= pivot) {
i = i + 1;
swap(nums, i, j);
}
}
swap(nums, i + 1, r);
return i + 1;
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
参考自:
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/solution/zui-xiao-de-kge-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。