代码随想录算法训练营第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>&。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端