LeetCode題目鏈接
https://leetcode.cn/problems/evaluate-reverse-polish-notation/
https://leetcode.cn/problems/sliding-window-maximum/
https://leetcode.cn/problems/top-k-frequent-elements/
題解
150.逆波蘭表達式求值、
不能用tokens[i] >= "0" && tokens[i] <= "9"
來判斷數字,因為會有三位數。被AI發現的bug。
239.滑動窗口最大值
拿到題目,經提示已經知道是用隊列。但是重要的是用隊列記錄什么。
看題解(視頻),維護一個單調隊列,由我們自己來實現,每次新加入一個元素到隊列里時,把前面所有小于其值的值都pop出隊列,維持隊列出口為當前窗口的最大值。
實現代碼的過程中,有一個不明白的點是,為什么當前維護的最大值不會是已經在窗口左側邊緣外的值?找到原因了,代碼寫的不是很對,要彈出窗口前面的那個值。
又改了兩個地方,一個是改成deque的實現,一個是新加入的值要與back()比較,如果比較的值更小要pop_back(),從尾部彈出,可以防止[3,1,2]以及其下一步的[1,2,0]這樣的隊列維護值發生。
347.前K個高頻元素
想了用hash來存,但排序會丟失下標的信息;再想到用map來存,但不好根據值排序。
看題解,發現用map排序行。于是寫了個下一回寫不出的代碼,主要是sort的cmp集成代碼,還有遍歷pair代碼也寫不出。感覺都是語法問題,寫幾次就會了。
接著看題解,語法也挺難,思路,要用到小頂堆,堆的數據結構和代碼沒怎么寫過,下回再補。
代碼
//150.逆波蘭表達式求值
#include <iostream>
#include <vector>
#include <string>
#include <stack>
using namespace std;class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for (int i = 0;i < tokens.size();i++) {if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {int tmp1 = st.top();st.pop();int tmp2 = st.top();st.pop();if (tokens[i] == "+") st.push(tmp1 + tmp2);else if (tokens[i] == "-") st.push(tmp2 - tmp1);else if (tokens[i] == "*") st.push(tmp1 * tmp2);else st.push(tmp2 / tmp1);}else {st.push(stoi(tokens[i]));}}return st.top();}
};int main() {vector<string> tokens = { "10","6","9","3","+","-11","*","/","*","17","+","5","+" };Solution s;printf("%d", s.evalRPN(tokens));return 0;
}
//239.滑動窗口最大值
#include <iostream>
#include <vector>
#include <queue>
using namespace std;class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> result;//queue<int> que;deque<int> que;for (int i = 0;i < k;i++) {/*while (!que.empty() && que.front() < nums[i]) {que.pop_front();}*/while (!que.empty() && nums[i] > que.back()) {que.pop_back();}que.push_back(nums[i]);}result.push_back(que.front());for (int i = k;i < nums.size();i++) {if (!que.empty() && nums[i - k] == que.front()) {que.pop_front();}/*while (!que.empty() && que.front() < nums[i]) {que.pop();}*/while (!que.empty() && nums[i] > que.back()) {que.pop_back();}que.push_back(nums[i]);result.push_back(que.front());}return result;}
};int main() {vector<int> nums = { 1,3,1,2,0,5 };int k = 3;Solution s;vector<int> result = s.maxSlidingWindow(nums, k);for (int i = 0;i < result.size();i++) {printf("%d ", result[i]);}return 0;
}
//347.前K個高頻元素
vector<int> topKFrequent(vector<int>& nums, int k) {map<int, int> hash;for(int i = 0;i < nums.size();i++){hash[nums[i]]++;}vector<pair<int, int>> tmp(hash.begin(), hash.end());sort(tmp.begin(), tmp.end(), [](const pair<int, int>& a, const pair<int, int>& b) {return a.second > b.second; // 按照值降序排列});vector<int> result;int num = 0;for(const auto& pair : tmp){if(num < k){result.push_back(pair.first);num++;}}return result;}