代码随想录算法训练营第23天(补第11天)|150. 逆波兰表达式求值,239. 滑动窗口最大值,347.前 K 个高频元素

150. 逆波兰表达式求值

文章链接:https://programmercarl.com/0150.逆波兰表达式求值.html#算法公开课
题目链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long> st;
        long long result;
        for(int i=0;i<tokens.size();i++){
            if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/"){
                long long res=0;
                long long num1=st.top();
                st.pop();
                long long num2=st.top();
                st.pop();
                if(tokens[i]=="+") res=num2+num1;
                else if(tokens[i]=="-") res=num2-num1;
                else if(tokens[i]=="*") res=num2*num1;
                else if(tokens[i]=="/") res=num2/num1;
                st.push(res);
            }
            else st.push(stoll(tokens[i]));
        }
        result=st.top();
        return result;
    }
};

239. 滑动窗口最大值

文章链接:https://programmercarl.com/0239.滑动窗口最大值.html#算法公开课
视频链接:https://www.bilibili.com/video/BV1XS4y1p7qj/?vd_source=6cb513d59bf1f73f86d4225e9803d47b
题目链接:https://leetcode.cn/problems/sliding-window-maximum/

class Solution {
private:
    //实现一种数据结构deque,使得其能完成pop出移走的元素,push新加的元素,并front得到队列头元素
    //队列只维护最大的元素,队内是递减的数列
    class Mydeque{
    public:
        deque<int> que;
        //实现pop操作,如果队列头元素与滑动窗口移出的元素相同,则真pop
        void pop(int val){
            if(!que.empty()&&val==que.front()) que.pop_front();
        }
        //实现push操作,如果push的时候,前面的值不能大于压入的值,否则移除前面的值
        void push(int val){
            while(!que.empty()&&que.back()<val) que.pop_back();  //注意:que.back()不可以等于val!!!
            que.push_back(val);
            }
        //队列头元素即为我们所求窗口内的最大元素
        int front(){
            return que.front();
        }
    };

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

347.前 K 个高频元素

文章链接:https://programmercarl.com/0347.前K个高频元素.html#算法公开课
视频链接:https://www.bilibili.com/video/BV1Xg41167Lz/?vd_source=6cb513d59bf1f73f86d4225e9803d47b
题目链接:https://leetcode.cn/problems/top-k-frequent-elements/description/

前置知识
priority_queue:
定义:priority_queue<Type, Container, Functional>
Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆

//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;

//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)

————————————————
原文链接:https://blog.csdn.net/weixin_36888577/article/details/79937886

class Solution {
    //自定义比较类
    class comparison{
    public:
        //重构()运算符
        bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){
            return lhs.second>rhs.second;  //小顶堆
        }
    };
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        //统计各个元素的频率
        unordered_map<int,int> map;
        for(int i=0;i<nums.size();i++){
            map[nums[i]]++;
        }
        //定义小顶堆
        priority_queue<pair<int,int>,vector<pair<int,int>>,comparison> que;
        for(unordered_map<int,int>::iterator it=map.begin();it!=map.end();it++){
            que.push(*it); //优先级队列push进去就会自己排好序
            if(que.size()>k) que.pop();
        }

        //由于que内部小顶堆是从小到大排序的,所以输出转换成从大到小的顺序
        vector<int> result(k);
        for(int i=k-1;i>=0;i--){
            result[i]=que.top().first;
            que.pop();
        }
        return result;
    }
};

一些疑惑:为什么使用const pair<int,int>& 而不是pair<int,int>?

虽然可以直接使用 pair<int, int> 作为参数类型,但这会导致以下几个问题:

  • 性能问题:每次调用该函数时,都会复制 pair<int, int> 的对象。如果这个对象比较大,复制会带来额外的开销。
  • 额外的开销:即使 pair<int, int> 相对较小,频繁的复制仍然会影响性能,尤其是在需要多次调用的情况下。
  • 灵活性:如果你使用 const pair<int, int>&,你可以传入临时对象、常量对象或非常量对象,而直接使用 pair<int, int> 可能会限制传递的对象类型。

因此,虽然可以直接使用 pair<int, int>,但为了性能和灵活性,通常推荐使用 const pair<int, int>&。

posted @   W-Vicky11  阅读(205)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示