题目描述
给定一个整数数组 temperatures
,表示每天的温度,返回一个数组 answer
,其中 answer[i]
是指对于第 i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0
来代替。
初始答案
我先开始自己用栈瞎写了一个,但是通过35/48,后面的就超出时间限制了。虽说知道是用单调栈,但是我解决的逻辑仍然是暴力搜索(两层循环)。
cpp
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int> ans(temperatures.size());
stack<int> s; // 存放index
int cur_idx = 0;
while(cur_idx < temperatures.size()-1){
int idx = cur_idx + 1;
if(temperatures[idx] > temperatures[cur_idx]){ // 如果第二天的温度更高,直接放1
ans[cur_idx] = 1;
}
else {
while(idx < temperatures.size() && temperatures[idx] <= temperatures[cur_idx]){ // 如果第二天的温度更低,则while循环找
s.push(idx);
idx++;
}
int s_size = s.size();
if(idx == temperatures.size()) ans[cur_idx] = 0;
else ans[cur_idx] = s_size+1;
for(int i = 0; i < s_size; i++){
s.pop();
}
}
cur_idx++;
}
return ans;
}
};
后续分析
单调栈的顺序应该是非单调递减的(栈头<=栈底),也就是说我们放进去的值总要小于当前栈头。于是我们在遍历入栈的时候就有两种情况:
- 当前遍历元素
T[idx] <= T(s.top())
:此时加入栈不会破坏当前趋势,所以不做其他操作。 - 当前遍历元素
T[idx] > T(s.top())
:我们要将当前遍历元素的索引idx
入栈后,就破坏了非单调递减的趋势,所以我们可以一步一步的记录当前idx
和栈顶元素索引s.top()
的距离,然后将栈顶元素pop出栈,依此循环直到栈顶元素比当前T[idx]
大,即满足非单调递减。
修改后的代码:
cpp
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int> ans(temperatures.size(), 0);
stack<int> s; // 存放index
s.push(0);
for(int i = 1; i < temperatures.size(); i++) {
// 如果当前遍历元素大于栈顶元素,就计算两者index距离,记录在ans中,并让栈顶元素弹出
while(!s.empty() && temperatures[i] > temperatures[s.top()]) {
ans[s.top()] = i - s.top();
s.pop();
}
s.push(i);
}
return ans;
}
};