1、快排思想
①返回前k个数
void quickK(vector<int> &arr, int k, int left, int right)
{
if (left >= right) //重要,控制递归结束
return;
int key = arr[left];
int i = left, j = right;
while (i < j)
{
while (i < j && arr[j] >= key)
j--;
if (i < j)
arr[i++] = arr[j];
while (i < j && arr[i] <= key)
i++;
if (i < j)
arr[j--] = arr[i];
arr[i] = key;
if (i - left + 1 >= k) //判断对哪边进行继续排序
quickK(arr, k, left, i);
else
quickK(arr, k - (i - left + 1), i + 1, right);
}
}
vector<int> findKthSmall(vector<int> nums, int k)
{
quickK(nums, k, 0, nums.size() - 1);
return vector<int>(nums.begin(), nums.begin() + k);
}
②返回第k个数
int quikSort(vector<int>& nums, int left, int right) {
if (left >= right) {
return left;
}
int key = nums[left];
int i = left, j = right;
while (i < j) {
while (j > i && nums[j] >= key) {
j--;
}
if (j > i) {
nums[i++] = nums[j];
}
while (j > i && nums[i] <= key) {
i++;
}
if (j > i) {
nums[j--] = nums[i];
}
nums[i] = key;
}
return i;
}
int findKth(vector<int>& nums, int left, int right, int k) {
int ind = quikSort(nums, left, right);
if (k == right - ind + 1) {
return nums[ind];
}
else if (k < right - ind + 1)
{
return findKth(nums, ind+1, right, k);
}
else {
return findKth(nums, left, ind-1, k - (right - ind + 1));
}
}
2、使用大顶堆/小顶堆
//大小顶堆
vector<int> quickK(vector<int> &arr, int k)
{
//priority_queue<int, vector<int>, less<int>> big_que; //大顶堆,返回最大的k个
priority_queue<int, vector<int>, greater<int>> big_que; //小顶堆,返回最小的k个
for (auto &n : arr)
big_que.push(n);
vector<int> res;
for (int i = 0; i < k; i++)
{
int tmp = big_que.top();
big_que.pop();
res.push_back(tmp);
}
return res;
}
3、计数排序
(1)遍历,获取最大,最小值
(2)创建数组,大小为(最大值-最小值+1)
(3)遍历数组,获取第k个数字。