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

LeetCode 239.滑动窗口最大值

题目链接:239.滑动窗口最大值

踩坑:一开始觉得很简单,暴力求解即可,之后看了视频,学习了思路。因为先看了视频,所以没踩什么坑

思路:核心是怎么维护窗口内的数。固定窗口每次向后移动一格的行为很像队列,所以考虑使用队列这一数据结构。队列在push元素时,判断队尾元素是否大于新元素,若小于则pop队尾元素(所以需要双端队列),直到队尾大于等于新元素,再将新元素push,即保持队列中元素的递减(非严格)。这样可以将窗口内最大的元素保持在队首。pop时需要判断队首元素与窗口抛弃的元素是否相等,相等才pop,不相等说明在之前push阶段已经pop了。

代码:

class Solution {
public:
    deque<int> q;

    void pop(int a)
    {
        if(!q.empty() && q.front() == a) q.pop_front();
    }

    void push(int a)
    {
        while(!q.empty() && q.back() < a) q.pop_back();
        q.push_back(a);
    }

    int getMax()
    {
        return q.front();
    }

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

LeetCode 347.前K个高频元素

题目链接:347.前K个高频元素

踩坑:对大小堆的使用不熟悉(传入cmp需要构建结构体或类对()进行重载,且a>b是小顶堆,且cmp传参之前必须对底层存储结构传参)

思路:使用字典统计每个数字出现的频次。对字典中的键值对以值为基准降序排序。

  1. 使用vector将字典中的pair拿出来,使用sort函数搭配自定义cmp函数对vector排序。
  2. 使用优先级队列,只需要维护k的大小,对每个push进来的pair以second为基准比较。

代码:

class Solution {
public:
    struct cmp
    {
        bool operator()(pair<int, int>& a, pair<int, int>& b)
        {
            return a.second > b.second;
        }
    };
    
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> m;
        vector<int> result;
        for(int i = 0; i < nums.size(); i++)
        {
            m[nums[i]]++;
        }
        priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> q;
        for(auto it = m.begin(); it != m.end(); it++)
        {
            q.push(*it);
            if(q.size() > k) q.pop();
        }
        for(int i = 0; i < k; i++)
        {
            result.push_back(q.top().first);
            q.pop();
        } 
        return result;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值