150. 逆波兰表达式求值
利用栈的特性,每次用top和第二个top计算,结果为新top
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> stk;
int ans = 0;
for(string s : tokens){
int x = 0, y = 0;
if(s == "+" || s == "-" || s == "*" || s == "/"){
x = stk.top();
stk.pop();
y = stk.top();
stk.pop();
if(s == "+"){
stk.push(x + y);
}else if(s == "-"){
stk.push(y - x);
}else if(s == "*"){
stk.push(x * y);
}else if(s == "/"){
stk.push(y / x);
}
}else{
stk.push(stoi(s));
}
}
return stk.top();
}
};
239. 滑动窗口最大值
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> q;
int n = nums.size();
vector<int> ans;
for(int i = 0; i < k && i < n; i++){
while((!q.empty()) && q.back() < nums[i]){
// 当窗口内某元素右侧出现比自己大的元素时,此时窗口最大值与该元素无关
// 当队列中某元素被删除,一定是窗口内出现了比它还大的值
q.pop_back();
}
q.push_back(nums[i]); // 窗口的最新元素一定要入队
}
ans.push_back(q.front()); // 第一个窗口的最大值
for(int i = k; i < n; i++){ // 维护窗口右侧
while((!q.empty()) && q.back() < nums[i]){
// 当窗口内某元素右侧出现比自己大的元素时,此时窗口最大值与该元素无关
// 当队列中某元素被删除,一定是窗口内出现了比它还大的值
q.pop_back();
}
if(!q.empty() && nums[i - k] == q.front()){
q.pop_front(); // 窗口不再包含最大值
}
q.push_back(nums[i]); // 窗口的最新元素一定要入队
ans.push_back(q.front());
}
return ans;
}
};
347.前 K 个高频元素
class Solution {
public:
// 优先队列
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> mp;
for(int num : nums){
mp[num]++; // 记录每个元素出现的次数
}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
// 默认大顶堆,使用greater改为小顶堆
for(pair p : mp){
if(pq.size() == k && pq.top().first < p.second){
cout << pq.top().first <<endl;
pq.pop();
pq.push({p.second, p.first});
}else if(pq.size() < k){
pq.push({p.second, p.first});
cout << pq.top().first <<endl;
}
}
vector<int> ans;
while(!pq.empty()){
ans.push_back(pq.top().second);
pq.pop();
}
return ans;
}
};
71.简化路径
class Solution {
public:
string simplifyPath(string path) {
stack<string> stk;
int n = path.size();
for(int i = 0; i < n;){
if(path[i] == '/'){ // 只记录文件名
i++;
while(i < n && path[i] == '/'){ // 找到文件名的左侧'/'
i++;
}
string fname;
while(i < n && path[i] != '/'){ // 找到文件夹的右侧'/'
fname += path[i++];
}
if(fname == "."){
continue;
}else if(fname == ".."){
if(!stk.empty()){
stk.pop();
}
}else if(fname != ""){ // 其余情况全部算作文件夹
stk.push(fname);
}
}
}
string ans;
while(!stk.empty()){
string path_ans = stk.top();
if(ans.empty()){
ans = '/' + path_ans;
}else{
ans = "/" + path_ans + ans;
}
stk.pop();
}
if(ans == ""){
ans = "/";
}
return ans;
}
};