首页 > 编程语言 >代码随想录算法训练营第十三天 | 239. 滑动窗口最大值 347. 前k个高频元素

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

时间:2024-05-20 18:31:21浏览次数:21  
标签:347 元素 随想录 queue vector que priority 第十三天 dq

239. 滑动窗口最大值

题目链接 文章讲解 视频讲解

思路:使用单调队列,来维护有可能成为最大值的元素;
   当窗口向右滑动时,判断移除的元素是否是队首元素如果是的话出队;
   新加入的元素依次和队尾元素作比较,如果大于队尾元素则将队尾元素循环出队,这样可以保证队列中始终维持一个窗口中当前的最大值,和将来可能成为最大值的元素

class Solution {
public:
    // 入队:当队不为空且当前值比队尾元素大则循环出队,然后当前值插入队尾
    void enqueue(deque<int>& dq, int val) {
        while(!dq.empty()) {
            if(dq.back() < val) {
                dq.pop_back();
                continue;
            }
            break;
        }
        dq.push_back(val);
    }
    // 出队
    void dequeue(deque<int>& dq) {
        dq.pop_front();
    }
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int> dq;
        vector<int> ans;
        // 将前k个元素入队
        for(int i = 0; i < k; ++i) {
            enqueue(dq, nums[i]);
        }
        // 将前k个元素中最大值插入结果集中
        ans.push_back(dq.front());
        // 处理剩下的元素
        for(int i = k; i < nums.size(); ++i) {
            // 如果队首元素是当前要移除窗口的元素,则出队
            if(dq.front() == nums[i - k]) {
                dequeue(dq);
            }
            // 将新元素入队
            enqueue(dq, nums[i]);
            // 更新窗口之后的最大值加入结果集中
            ans.push_back(dq.front());

        }
        return ans;
    }
};

347. 前k个高频元素

题目链接 文章讲解 视频讲解
关键词:
   频率 -> 使用map来统计
   前k个 -> 一般使用堆来解决
如何建立堆:
    在c++中使用priority_queue来建立堆

priority_queue的模板声明如下:

template <class Type, class Container=vector<type>, class Compare=less <typename Container:: value_type>>
class priority_queue
  • 第一个模板参数表示priority_queue要存储的元素:
  • 第二个模板参数表示priority_queue的底层容器,默认为vector,也可以指定其他类型
  • 第三个模板参数表示priority_queue元素之间比较规则的比较函数或函数对象
priority_queue<pair<int, int>, vector<pair<int, int>>, MyCompare> pri_que;

接下类需要写比较函数对象(仿函数)

    class MyCompare {
    public:
        bool operator()(pair<int, int> &lhs, pair<int, int> &rhs) {
            return lhs.second > rhs.second;
        }
    };

此处用 > 是小根堆,< 是大根堆

class Solution {
    class MyCompare {
    public:
        bool operator()(pair<int, int> &lhs, pair<int, int> &rhs) {
            return lhs.second > rhs.second;
        }
    };
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        map<int, int> m;
        vector<int> ans;
        // 用map统计每个元素出现的频率
        for(int val : nums) {
            m[val]++;
        }
        // 建立小根堆
        priority_queue<pair<int, int>, vector<pair<int, int>>, MyCompare> pri_que;
        // 将map中的元素插入堆中,
        for(auto it = m.begin(); it != m.end(); ++it) {
            pri_que.push(*it);
            // 由于只求前k个,所以当超过k个元素时,从堆中弹出元素
            if(pri_que.size() > k) pri_que.pop();
        }
        // 将满足条件的元素加入结果集中
        while(!pri_que.empty()) {
            ans.push_back(pri_que.top().first);
            pri_que.pop();
        }
        return ans;
    }
};

标签:347,元素,随想录,queue,vector,que,priority,第十三天,dq
From: https://www.cnblogs.com/cscpp/p/18202575

相关文章