image

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int>dl;
        for(int i=0;i<nums.size();i++){
            dl.push(nums[i]);
        }
        for(int i=0;i<k-1;i++){
            dl.pop();
        }
        return dl.top();
    }
};

image

思路:1.记录词和词频对应关系用map,map的first是key,second是value  2.处理多次最大元素问题使用优先队列(默认大根堆)

 

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        vector<int>ans;
        priority_queue<pair<int,int>>dl;
        map<int,int>mp;
        for(int i=0;i<nums.size();i++){
            mp[nums[i]]++;
        }
        for(auto i:mp) {
            dl.push({i.second,i.first});//词频,词
        }
        for(int i=0;i<k;i++){
            ans.push_back(dl.top().second);
            dl.pop();
        }
        return ans;
    }
};

image

image

优先队列的自定义排序

#include <iostream>
#include <queue>
using namespace std;

// 全局比较函数:返回 true 表示 a 应排在 b 后面(小顶堆)
bool cmpInt(const int& a, const int& b) {
    return a > b;  // 大的 a 往后放,堆顶是最小值
}

int main() {
    // 第三个参数是函数指针类型(&cmpInt 可省略,函数名即指针)
    priority_queue<int, vector<int>, decltype(&cmpInt)> pq(cmpInt);

    pq.push(5);
    pq.push(2);
    pq.push(7);

    // 出队:2 → 5 → 7
    while (!pq.empty()) {
        cout << pq.top() << " ";
        pq.pop();
    }
    return 0;
}
// 输出:2 5 7

法一:优先队列(就用一个优先队列)超时

 

class MedianFinder {
private:
    priority_queue<int>dl;
public:
    MedianFinder() {
        
    }
    void addNum(int num) {
        dl.push(num);
    }
    double findMedian() {
        int l=dl.size();
        priority_queue<int>temp;
        temp=dl;
        if(l%2!=0){//队列中有奇数个元素。
          for(int i=0;i<l/2;i++){
            temp.pop();
          }
          return temp.top();
        }
        else{
            double y=0;
            for(int i=0;i<(l/2)-1;i++){
                temp.pop();
            }
            y=y+temp.top();
            temp.pop();
            y+=temp.top();
            temp.pop();
            return y/2;

        }
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

 方法二:用两个堆

一个大根堆,一个小根堆

用一个大根堆:存放小于等于中位数,因为关键是存放最接近中位数的那个数,也就是这个队列中的最大数,为了快速获取这个最大值用大根堆

用一个小根堆:存放大于中位数的数,因为关键是存放最接近中位数的那个数,也就是这个队列中的最小数,为了快速获取这个最小值用小根堆\

class MedianFinder {
public:
    priority_queue<int,vector<int>,greater<int>>que_Max;//存放大于中位数 小根堆
    priority_queue<int,vector<int>,less<int>>que_Min;//存放小于等于中位数 大根堆
/*因为数组中元素可能是奇数个或偶数个
1.奇数个元素时 que_ Min中元素比que_Max元素多一个-->此时中位数是que_ Min.top()
2.偶数个元素时que_Min元素和que_Max元素一样多(que_ Min.top()+que_Max.top())/2.0


*/
    MedianFinder() {}

    void addNum(int num) {
       if(que_Min.size()==0||(num<=que_Min.top())){//num小于中位数
        que_Min.push(num);
        if(que_Max.size()+1<que_Min.size()){//放入以后小于等于中位数的队列数字多了一个,弹出小于等于中位数的那个大根堆的顶(最大值)放入小根堆
        que_Max.push(que_Min.top());
        que_Min.pop();
        }
       }
       else{
        que_Max.push(num);
        if(que_Max.size()>que_Min.size()){
            que_Min.push(que_Max.top());
            que_Max.pop();
        }
       }
    }

    double findMedian() {
      if(que_Max.size()<que_Min.size()){
        return que_Min.top();
      }
      else{
        return (que_Max.top()+que_Min.top())/2.0;
      }
    }
};

 

posted @ 2025-11-26 09:14  Annaprincess  阅读(1)  评论(0)    收藏  举报