本题本来并不难,记录下来是因为有一个坑(while条件的先后顺序)。
这道题用到的是单调栈的数据结构。什么是单调栈?可分为以下两种:
- 单调递增栈:栈中数据出栈的序列为单调递增序列
- 单调递减栈:栈中数据出栈的序列为单调递减序列
适用的范围大致是:对于每个元素,在数组中寻找到一个比其大(小)的元素。
模板代码:
stack<int> st;
//此处一般需要给数组最后添加结束标志符
for (遍历这个数组)
{
if (栈空 || 栈顶元素大于等于当前比较元素)
{
入栈;
}
else
{
while (栈不为空 && 栈顶元素小于当前元素)
{
栈顶元素出栈;
更新结果;
}
当前数据入栈;
}
}
本题的思路也大致就是如此:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
vector<int> day(T.size(),0); //全部初始化为0,那么未出栈的元素day[i]=0,后续不需要再处理
stack<int> s;
for(int i=0;i<T.size();i++){
if(s.empty()||T[s.top()]>=T[i])
s.push(i);
else {
while(!s.empty()&&T[s.top()]<T[i]) //!s.empty()一定要放在前面,原因见后
{
day[s.top()]=i-s.top();
s.pop();
}
s.push(i);
}
}
return day;
}
};
T = [73, 74, 75, 71, 69, 72, 76, 73]
若条件为:while(T[s.top()]<T[i]&&!s.empty()) ,while循环时会先计算前面的条件T[s.top()]<T[i],若前面的条件为true,才计算后面的条件的值。
若i=1,第二次进入while,首先计算T[s.top()]<T[i],此时栈为空,s.top()==-1,即T[-1]<74,而程序在T[-1]处卡死,就会报错。
而若条件改为while(!s.empty()&&T[s.top()]<T[i]),相同的情况,i=1,第二次进入while,此时!s.empty()==false,不会计算后面的条件的值(短路与),因此不会报错。
短路与:(A&&B)
若A为false,不计算B,表达式为false;
若A为true,计算B,表达式值为B。
因此,我们需要把能快速确定整个表达式结果true或false的表达式放在前面,这样由于短路运算后面的表达式可能不会被运算到,节省处理器的运算时间。