150. 逆波兰表达式求值
思路
典型的计算机思维题目,用栈的思维
代码随想录
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> st;
for (int i = 0; i < tokens.size(); i++) {
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
long long nums1 = st.top();
st.pop();
long long nums2 = st.top();
st.pop();
if (tokens[i] == "+") st.push(nums2 + nums1);
if (tokens[i] == "-") st.push(nums2 - nums1);
if (tokens[i] == "*") st.push(nums2 * nums1);
if (tokens[i] == "/") st.push(nums2 / nums1);
}else{
st.push(stoll(tokens[i]));
}
}
return st.top();
}
};
收获
stol
函数,将string
转换为long
,stoll
将string
转换为long long
;
239. 滑动窗口最大值
思路
第一种暴力解法:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
for (int i = 0; i < nums.size() && i + k <= nums.size(); i++) {
// 在预定义宏中 #include <climits>
int maxValue = INT_MIN;
for (int j = i; j < i + k ; j++) {
maxValue = max(maxValue, nums[j]);
}
res.push_back(maxValue);
}
return res;
}
};
代码随想录
构建单调队列
class Solution {
private:
class MyQueue {
public:
deque<int> que;
void pop(int value) {
if (!que.empty() && value == que.front()) {
que.pop_front();
}
}
void push(int value) {
while (!que.empty() && value > que.back()) {
que.pop_back();
}
que.push_back(value);
}
int getMaxValue() {
return que.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
MyQueue que;
vector<int> res;
for (int i = 0; i < k; i++) {
que.push(nums[i]);
}
// 在 result 中放入最大值
res.push_back(que.getMaxValue());
for (int i = k; i < nums.size(); i++) {
// 弹出不在窗口的值
que.pop(nums[i - k]);
// 放入新进窗口的值
que.push(nums[i]);
// getMaxValue
res.push_back(que.getMaxValue());
}
return res;
}
};
收获
// 在预定义宏中 #include <limits>
int maxValue = INT_MIN;
在自己构建类进行代码操作时,现在主函数中设计出框架,再根据框架中每一步需要的功能在类中设计对应的函数。
347.前 K 个高频元素
代码随想录
class Solution {
public:
class myComparison {
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 = 0; i < nums.size(); i++) {
map[nums[i]]++;
}
// 小顶堆构建方法
priority_queue<pair<int, int>, vector<pair<int, int>>, myComparison> pri_que;
for (unordered_map<int ,int>::iterator it = map.begin(); it != map.end(); it++) {
pri_que.push(*it);
if (pri_que.size() > k) {
pri_que.pop();
}
}
vector<int> res(k);
for (int i = 0; i < k ; i++) {
res[i] = pri_que.top().first;
pri_que.pop();
}
return res;
}
};
收获
- 大顶堆:根节点比
child
大; - 小顶堆:根节点比
child
小; - 从小到大排就是小顶堆,从大到小排就是大顶堆。
- 堆的弹出是从堆顶开始弹出,因此本题需要使用小顶堆;