剑指 Offer 40. 最小的k个数https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof/
法1:二叉堆
通过最小堆,直接筛选出最小的k个数
vector<int> getLeastNumbers(vector<int>& arr, int k) {
priority_queue<int, vector<int>, greater<int>> minHeap;
for (const int num : arr)
{
minHeap.push(num);
}
vector<int> res(k);
for (int i = 0; i < k; ++i)
{
res[i] = minHeap.top();
minHeap.pop();
}
return res;
}
法2:快速选择
二分+快排 结合
将最小的k个数 分到一边
int partition(vector<int>& nums, const int left, const int right)
{
// base case
if (left >= right)
{
return left;
}
int pivot = nums[left];
int i = left + 1, j = right;
while (i <= j)
{
while (i <= right && nums[i] <= pivot)
{
++i;
}
while (j > left && nums[j] > pivot)
{
--j;
}
if (i > j)
{
break;
}
swap(nums[i], nums[j]);
}
swap(nums[left], nums[j]);
return j;
}
vector<int> getLeastNumbers(vector<int>& arr, int k) {
int n = arr.size();
int left = 0, right = n - 1;
while (left <= right)
{
int mid = partition(arr, left, right);
if (mid < k - 1)
{
left = mid + 1;
}
else if (mid > k - 1)
{
right = mid - 1;
}
else
{
break;
}
}
vector<int> res(k);
for (int i = 0; i < k; ++i)
{
res[i] = arr[i];
}
return res;
}