代码随想录算法训练营第十一天 239. 滑动窗口最大值 347.前 K 个高频元素

文章讲述了如何使用单调队列(自定义双端队列)解决LeetCode中的239滑动窗口最大值问题,以及如何利用小顶堆(优先级队列)实现347前K个高频元素问题,重点介绍了队列和堆在这些问题中的关键作用和优化策略。
摘要由CSDN通过智能技术生成

 239. 滑动窗口最大值

文档讲解:代码随想录 (programmercarl.com)

视频讲解:单调队列正式登场!| LeetCode:239. 滑动窗口最大值_哔哩哔哩_bilibili

状态:没做出来

         思路上还是很复杂的,因为这题的解法是要自定义一个单调减队列,也就是说,如果入队的时候前面有比当前入队的值小的数,都要出队,考虑到不可能队列里的元素都比当前入队的元素的值要小,所以这个时候出队必须要从队尾出,当然由于是滑动窗口所以队列中的最大值有被弹出的可能,所以还是要保留队头出队的功能。

        用双端队列可以很好地解决这个问题,因为双端队列就是从队列两端出队的。而且,容器适配器stack,queue都是由双端队列实现的,也就是deque。

        为什么想到用队列?滑动窗口的机制本身就很像队列,队头出,队尾进。

class Solution {
public:
    void pop(deque<int>& deq,int value){
        if(!deq.empty() && value == deq.front()){
            deq.pop_front();
        }
    }

    void push(deque<int>& deq,int value){
        while(!deq.empty() && value > deq.back()){
            deq.pop_back();
        }
        deq.push_back(value);
    }

    int getMaxValue(deque<int>& deq){
        return deq.front();
    }

    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int> deq;
        for(int i = 0;i < k;i++){
            push(deq,nums[i]);
        }
        vector<int> result;
        result.push_back(getMaxValue(deq));
        for(int i = k;i < nums.size();i++){
            pop(deq,nums[i-k]);
            push(deq,nums[i]);
            result.push_back(getMaxValue(deq));
        }
        return result;
    }
};

347.前 K 个高频元素

文档讲解:代码随想录 (programmercarl.com)

视频讲解:优先级队列正式登场!大顶堆、小顶堆该怎么用?| LeetCode:347.前 K 个高频元素_哔哩哔哩_bilibili

状态:没做出来

        这道题的思路其实不难,用map将数组中所有元素以及出现次数都记录下来,然后把这些数据,导入另一种自带排序功能的容器,排一下序找前k个就行。

         在leetcode上看到有人用vector来承接map的数据,当然可以,但是这样排序把所有元素都排了,其实并不需要把所有元素都排序,可以用小顶堆实现。

        为什么是小顶堆?1. 在C++中priority_queue可以实现小顶堆。有现成的数据结构。2.只需要保持小顶堆里的是前k个高频元素即可,多余的可以出队。3. 每次出队都是在队头,所以队头应该是频率最低的元素。

        这题真正的难点是语法,很难理解。等后面统一总结的时候把它搞定。现在任然一知半解。

 class Solution {
public:
    static bool cmp(const pair<int,int> &lhs,const pair<int,int> &fls){
        return lhs.second > fls.second;
    }

    vector<int> topKFrequent(vector<int>& nums, int k) {
       unordered_map<int,int> umap;
       for(int i = 0 ;i < nums.size();i++){
           umap[nums[i]]++;
       }

        priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(&cmp)> p_queue(&cmp);

        for(unordered_map<int,int>::iterator it = umap.begin();it != umap.end();it++){
            p_queue.push(*it);
            if(p_queue.size() > k){
                p_queue.pop();
            }
        }

        vector<int> result(k);
        for(int i = k-1;i >=0;i--){
            result[i] = p_queue.top().first;
            p_queue.pop();
        }
        return result;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值