class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> num;
for(string i : tokens){
int tmp1,tmp2;
if((i[0]>='0'&&i[0]<='9')||(i[0]=='-'&&i.size()>1)){
int number=0,j=i.size()-1,mi=1;
while(j>=0){
if(i[j]!='-'){
number+=mi*(i[j]-'0');
mi=10*mi;
}else{
number=-number;
}
j--;
}
num.push(number);
}else{
int tmp1,tmp2;
tmp1=num.top();
num.pop();
tmp2=num.top();
num.pop();
if(i[0]=='+'){
num.push(tmp2+tmp1);
}else if(i[0]=='-'){
num.push(tmp2-tmp1);
}else if(i[0]=='*'){
num.push(tmp2*tmp1);
}else{
num.push(tmp2/tmp1);
}
}
}
return num.top();
}
};
将数字压入堆栈,遇到计算就弹出两个数进行运算,再压回堆栈即可。
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int>q;
vector<int>max(nums.size()-k+1,0);
int i=0;
while(i<k){
if(q.empty()){
q.push_back(nums[i]);
}else{
if(nums[i]<=q.back()){
q.push_back(nums[i]);
}else{
while(!q.empty()&&nums[i]>q.back()){
q.pop_back();
}
q.push_back(nums[i]);
}
}
i++;
}
max[i-k]=q.front();
while(i<nums.size()){
if(nums[i-k]==q.front()){
q.pop_front();
}
if(nums[i]<=q.back()){
q.push_back(nums[i]);
}else{
while(!q.empty()&&nums[i]>q.back()){
q.pop_back();
}
q.push_back(nums[i]);
}
i++;
max[i-k]=q.front();
}
return max;
}
};
在窗口滑动的过程中,如果滑出的数字等于队列头的数字,即代表最大的数字已经滑出窗口,队列在队列头进行弹出,对滑入窗口的数字,如果数字大于队列尾的数,那说明队列中的数字都不可能是窗口中最大的数,就将队列清空,将新的数加入队尾,如果小于队列尾的数,则队列中的数都是在滑动过程中可能是窗口中最大的数,所以将该数直接加入队尾。
class Solution {
public:
class min{
public:
bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
return lhs.second > rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int>map;
for(int i:nums){
map[i]++;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, min> pq;
for(unordered_map<int,int>::iterator it=map.begin();it!=map.end();it++){
pq.push(*it);
if(pq.size()>k){
pq.pop();
}
}
vector<int>result(k);
for(int i=k-1;i>=0;i--){
result[i]=pq.top().first;
pq.pop();
}
return result;
}
};
思想上是统计过频率后对频率进行排序,不过这个优先级队列和堆的操作笔者第一次接触,就先依葫芦画瓢了。