150.逆波兰表达式求值
给你一个字符串数组 tokens
,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
- 有效的算符为
'+'
、'-'
、'*'
和'/'
。 - 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
- 两个整数之间的除法总是 向零截断 。
- 表达式中不含除零运算。
- 输入是一个根据逆波兰表示法表示的算术表达式。
- 答案及所有中间计算结果可以用 32 位 整数表示。
示例 1:
输入:tokens = ["2","1","+","3","*"] 输出:9 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入:tokens = ["4","13","5","/","+"] 输出:6 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"] 输出:22 解释:该算式转化为常见的中缀算术表达式为:((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = ((10 * (6 / (12 * -11))) + 17) + 5 = ((10 * (6 / -132)) + 17) + 5 = ((10 * 0) + 17) + 5 = (0 + 17) + 5 = 17 + 5 = 22
思路: 注意到,后序表达式,那么用栈,遇到数字就压入栈,遇到运算符就取两个数字出来运算,得到ans压入栈,继续循环直到没有元素可以读取。需要注意的是,如果过只给一个数字,那么需要用top()来获取。
代码实现:
class Solution {
public:int evalRPN(vector<string>& tokens) {int ans = 0;stack<int> stk;int num1 = 0, num2 = 0;for(int i = 0; i < tokens.size(); ++i) {if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {num1 = stk.top();stk.pop();num2 = stk.top();stk.pop();if(tokens[i] == "+") ans = num2 + num1;if(tokens[i] == "-") ans = num2 - num1;if(tokens[i] == "*") ans = num2 * num1;if(tokens[i] == "/") ans = num2 / num1;stk.push(ans);}else {stk.push(stoi(tokens[i]));}}ans = stk.top();return ans;}
};
239.滑动窗口最大值
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 31 [3 -1 -3] 5 3 6 7 31 3 [-1 -3 5] 3 6 7 51 3 -1 [-3 5 3] 6 7 51 3 -1 -3 [5 3 6] 7 61 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1 输出:[1]
思路:读题后发现很暴力很直接,很顺畅就用一个queue和一个vector写出了暴力的解法,感叹困难题不过尔尔,提交发现超时...真是事与愿违,后面学到了单调队列,用一个队列,维护队首的元素永远是最大的(下面维护的是下标),首先处理最前面k个元素,然后初始化需要返回的vector,然后再处理后面的元素,直到读取到最后一个元素。
代码实现:
class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {deque<int> deq;for(int i = 0; i < k; ++i) {while(!deq.empty() && nums[i] >= nums[deq.back()]) {deq.pop_back();}deq.push_back(i);}vector<int> ans = {nums[deq.front()]};for(int i = k; i < nums.size(); ++i) {while(!deq.empty() && nums[i] >= nums[deq.back()]) {deq.pop_back();}deq.push_back(i);while(deq.front() <= i - k) {deq.pop_front();}ans.push_back(nums[deq.front()]);}return ans;}
};
347.前k个高频元素
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
示例 2:
输入: nums = [1], k = 1 输出: [1]
思路:?直~~接返回二维数组,先用个哈希map来记录每个元素的出现次数,然后加入到二维数组中,sort()一下,需要个排序的条件?甩个lambda表达式,ok排完序了,建一个vector来把前k个结果接出去。
代码实现:
class Solution {
public:vector<int> topKFrequent(vector<int>& nums, int k) {unordered_map<int, int> map;for(int i = 0; i < nums.size(); ++i) {++map[nums[i]];}vector<vector<int>> vec;for(auto& [x, y] : map) {vec.push_back({x, y});}sort(vec.begin(), vec.end(), [](const vector<int>& a, const vector<int>& b) {return a[1] > b[1];});vector<int> res;for(int i = 0; i < k && i < vec.size(); ++i) {res.push_back(vec[i][0]);}return res;}
};