topK问题

Posted 卷起来卷起来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了topK问题相关的知识,希望对你有一定的参考价值。

topK问题常见形式:

  1. 找第K大(第K小)的数
  2. 找出最大(最小)的前K个数
  3. 求前K词频的单词

解决Top K问题方法:

  1. sort排序
  2. 最大堆最小堆
  3. 快速排序

使用最大最小堆:求最大的数用最小堆,求最小的数用最大堆;
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问题的主要内容,如果未能解决你的问题,请参考以下文章

TopK问题

解决TopK问题的方式

分治思想--快速排序解决TopK问题

多情景下的TopK问题

堆排序应用之topK问题

Java最小堆解决TopK问题