代码训练营第十一天|150. 逆波兰表达式求值,239. 滑动窗口最大值,347.前K个高频元素

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;
    }
};
  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值