刷题笔记13 栈与队列 Part III

滑动窗口最大值 高频元素

滑动窗口最大值

239. 滑动窗口最大值

法1:

	class Solution {
    //构造单调队列 按要求存取val
private:
    class SingleQueue{
    public:
        deque<int> myqueue;
        void pop(int val){
            if (!myqueue.empty() && val == myqueue.front())
                myqueue.pop_front();
        }
        void push(int val){
            while (!myqueue.empty() && val > myqueue.back()) {//此处使用的是while()循环
                myqueue.pop_back();
            }
            myqueue.push_back(val);
        }
        int front(){
            return myqueue.front();
        }
    };
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        SingleQueue sq;
        vector<int> result;
        for (int i = 0; i < k; ++i) {
            sq.push(nums[i]);
        }
        result.push_back(sq.front());
//使用for循环进行窗口移动
        int len = nums.size();
        for (int i = k; i < len; ++i) {
            sq.pop(nums[i-k]);
            sq.push(nums[i]);
            result.push_back(sq.front());
        }
        return result;
    }
};

前k个高频元素

347.前 K 个高频元素
法1: 暴力求解

     typedef pair<int,int> PAIR;
    struct CmpByVal{
        bool operator()(const PAIR& lhs,const PAIR& rhs){
            return lhs.second >= rhs.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        // 统计每个元素出现个数
        map<int, int> frequency;
        for (int& num : nums) {
            frequency[num]++;
        }

        // 根据元素出现个数从大到小排序
        vector<pair<int, int>> freVec(frequency.begin(), frequency.end());
        sort(freVec.begin(), freVec.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {
            return p1.second > p2.second;
        });

        // 将前k个元素放进结果数组
        vector<int> ans(k);
        transform(freVec.begin(), freVec.begin() + k, ans.begin(), [](const auto& p) {
            return p.first;
        });

        return ans;
    }

法2:
基本概念: 大顶堆/小顶堆
堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。



	 class mycomparsion {
    public:
        bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){
            return lhs.second > rhs.second;//按val进比较
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {

        // 统计每个元素出现个数
        unordered_map<int, int> frequency;
        for (int& num : nums) {
            frequency[num]++;
        }

        //小顶堆
        priority_queue< pair<int,int>,vector<pair<int,int>>,mycomparsion> pri_que;
//        priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pri_que;
        // 用固定大小为k的小顶堆,扫面所有频率的数值
        for(unordered_map<int,int>::iterator it = frequency.begin();it != frequency.end();it++){
            pri_que.push(*it);
            if (pri_que.size() > k)
                pri_que.pop();
        }
        // 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
        vector<int> ans(k);//构造函数使用k初始化 创建vector
        for (int i = k-1; i >=0; --i) {
            ans[i] =pri_que.top().first;
            pri_que.pop();
        }
        return ans;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值