倒计时day3。进入最后一章单调栈。第一题是每日温度https://leetcode.cn/problems/daily-temperatures/,本题需要给出该天之后第一次温度高于该天的日期是在几天后。明显可以使用两层for循环进行比较,效率较低。我们可以设想这样一种数据结构:它能存放当前遍历元素之前日期的信息,若找到第一次比某天温度高的日期就立即进行处理,同时还能是数据结构中的元素保持有序,这种数据结构就是单调栈。我们在这个栈中存放单调递增的元素,当遍历发现当前元素大于栈顶元素,立即记录两者下标的差值并弹出栈顶元素,若小于,就加入栈中,再次向后遍历,我们就能找到距离该元素最近的满足要求的元素下标。
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> st;
vector<int> result (temperatures.size(), 0);
st.push(0);
for (int i = 1; i < temperatures.size(); i++){
if (temperatures[i] <= temperatures[st.top()]) st.push(i);
else {
while(!st.empty() && temperatures[i] > temperatures[st.top()]){
result[st.top()] = i - st.top();
st.pop();
}
st.push(i);
}
}
return result;
}
};
第二题是下一个更大元素https://leetcode.cn/problems/next-greater-element-i/submissions/510912809/,一道简单题,上来先用暴力解法秒了。
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> result (nums1.size(), -1);
for (int i = 0; i < nums1.size(); i++){
for (int j = 0; j < nums2.size(); j++){
if(nums1[i] == nums2[j]){
for (int m = j + 1; m < nums2.size(); m++){
if (nums2[m] > nums1[i]) {result[i] = nums2[m]; break;}
}
}
}
}
return result;
}
};
用单调栈有点大炮打蚊子😄首先用map进行一个数值与下标的映射,方便快速找到各个元素的下标值。用上一题相同的逻辑进行处理。预处理部分还是很考验代码功底的。
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
stack<int> st;
vector<int> result(nums1.size(), -1);
if (nums1.size() == 0) return result;
unordered_map<int, int> umap;
for (int i = 0; i < nums1.size(); i++){
umap[nums1[i]] = i;
}
st.push(0);
for (int i = 1; i < nums2.size(); i++){
if (nums2[i] < nums2[st.top()]){
st.push(i);
}
else if (nums2[i] == nums2[st.top()]) st.push(i);
else {
while(!st.empty() && nums2[i] > nums2[st.top()]){
if (umap.count(nums2[st.top()]) > 0){
int index = umap[nums2[st.top()]];
result[index] = nums2[i];
}
st.pop();
}
st.push(i);
}
}
return result;
}
};