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;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值