topK问题
Posted 技术热爱者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了topK问题相关的知识,希望对你有一定的参考价值。
topK问题常见形式:
- 找第K大(第K小)的数
- 找出最大(最小)的前K个数
- 求前K词频的单词
解决Top K问题方法:
- sort排序
- 最大堆最小堆
- 快速排序
使用最大最小堆:求最大的数用最小堆,求最小的数用最大堆;
Quick Select算法:使用类似快排的思路,根据pivot划分数组
使用排序方法:排序后再寻找top K元素
举例:
最小的k个数:
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
快速排序方法:
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> res;
quicksort(arr, 0, arr.size()-1);
res.assign(arr.begin(), arr.begin()+k);
return res;
}
private:
void quicksort(vector<int>& arr, int l, int r) {
if (l>=r) return;
int i = l, j = r;
while (i < j) {
while (i <j && arr[j] >= arr[l]) j--;
while (i < j && arr[i] <= arr[l]) i++;
swap(arr[i], arr[j]);
}
swap(arr[l], arr[i]);
quicksort(arr, l, i - 1);
quicksort(arr, i+1, r);
}
};
最大堆:
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
if(arr.empty() || k == 0) {return {};}
vector<int> res(k);
priority_queue<int> max_heap;
for(int i = 0; i < k; ++i) {max_heap.push(arr[i]);} // 用 arr 的前 k 个数填充最大堆
for(int i = k; i < arr.size(); ++i) {
if(arr[i] < max_heap.top()){
max_heap.pop();
max_heap.push(arr[i]); // 循环更新最大堆
}
}
for(int i = 0; i < k; ++i) {
res[i] = max_heap.top(); // 填充 res
max_heap.pop();
}
return res;
}
};
知识补充:C++ 创建大顶堆和小顶堆的写法
- 优先队列有三个参数,其声明形式为:priority_queue< type, container, function>;。后两个参数可以省略,第一个参数不能省略。
- 构建大顶堆:
priority_queue max_heap;
或者:priority_queue<int,vector,less > max_heap; - 构建小顶堆:
priority_queue<int,vector,greater > min_heap;
以上是关于topK问题的主要内容,如果未能解决你的问题,请参考以下文章
Top K Frequent Elements 之 topk问题