150. 逆波兰表达式求值
逆波兰表达式是后缀表达式(运算符写在后面),我们平常用的是中缀表达式。
所以可以用栈来解决,当遇到运算符时弹出两个,再把他们的结果放进去
stack<int> s1;
for(int i=0;i<tokens.size();i++){
if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="/"||tokens[i]=="*"){
int x1=s1.top();
s1.pop();
int x2=s1.top();
s1.pop();
if(tokens[i]=="+")
s1.push(x2+x1);
if(tokens[i]=="-")
s1.push(x2-x1);
if(tokens[i]=="*")
s1.push(x1*x2);
if(tokens[i]=="/")
s1.push(x2/x1);
}
else{
s1.push(stoi(tokens[i]));
}
}
return s1.top();
注意token[i]==“-”而不是‘-’,单引号是char类型,而且需要用stoi将token[i]转化为int类型
滑动窗口最大值
题目描述和队列很像,可以考虑队列。
思路
当i和j同在窗口中时,j大,如果j在i的右边,那有j出现时i一定不可能是最大值,所以i已经可以移除掉。
而当前面弹出的元素和j相同时,说明j已经不在窗口中,可以弹出。
deque<int> dd;
for (int i = 0; i < k; i++) {
while (!dd.empty() && nums[i] > dd.back()) {
dd.pop_back();
}
dd.push_back(nums[i]);
}
vector<int> result;
for (int i = 0; i <= nums.size() - k; i++) {
result.push_back(dd.front());
if (i < nums.size() - k) {
while (!dd.empty() && nums[i + k] > dd.back()) {
dd.pop_back();
}
dd.push_back(nums[i + k]);
if (nums[i] == dd.front())
dd.pop_front();
}
}
return result;
347.前K个高频元素
统计元素出现频率,可以用哈希表中的map,key是元素,value为频率。
由于要给出前K个高频元素,说明要对频率进行排序
这里涉及到优先队列priority_queue,优先队列本质上是堆。
堆是完全二叉树(只有最后一行可以不被填满,不能没有左子树),每个父节点都不小于子节点(大顶堆)或都不大于子节点(小顶堆)。
优先队列缺省时用大顶堆来排序。
priority_queue<int> q;//等于
priority_queue<int, vector<int>, less<int> > a
小顶堆
priority_queue<int,vector<int>,greater<int> > q;
即是从小到大排
优先队列
priority_queue<Type, Container, Functional>
container为实现方式,可以是vector和deque,不能是list
Functional是比较方式/优先级
常用函数
top 访问队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
pop 弹出队头元素
swap 交换内容
当不是基本数据类型时,需要自定义比较方式
重载(),仿函数
class mycmp{
bool operator() (pair<int,int> p1,pair<int,int> p2){
return p1.second>p2.second;
}
左边大于右边时建立小顶堆,左小于右是大顶堆
比如类型为水果时:
priority_queue<fruit,vector<fruit>,myComparison> q;
排序方式的选择
需要维持堆中的元素在k个,超出k个弹出。
如果用大顶堆的话,那么每次弹出时将会把最大的弹出,
取个极端情况,假如我只用1个,那么第一次弹出,那么我会弹出许多个k,这样还要把全部都排一遍才能确定。
那么如果用小顶推,跳出的最小元素就不用管了
class mycomparision{
public:
bool operator()((pair<int,int> p1,pair<int,int> p2)){
return p1.second>p2.second;//小顶推用大于
}
}
注意写public:
不然默认private无法访问
创建优先队列
priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparision> q;
map的遍历
使用迭代器
迭代器可以视为一种抽象的指针
定义:容器类名::iterator 迭代器名
map<typename1, typename2>::iterator it;
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
q.push(*it);//*it就是迭代器指向的元素
if(q.size()>k)
q.pop();
}
完整代码
class Solution {
public:
class mycp{
public:
bool operator()(pair<int,int>p1,pair<int,int>p2){
return p1.second>p2.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
priority_queue <pair<int,int>,vector<pair<int,int>>,mycp> a;
map<int,int> mp;
for(int num:nums){
mp[num]++;
}
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
a.push(*it);
if(a.size()>k)
a.pop();
}
vector<int> ans;
while(!a.empty()){
ans.push_back(a.top().first);
a.pop();
}
return ans;
}
};