题目
其实说是动态规划,也不知道算不算,因为印象里动态规划比较难,这题相对比较容易就能解开。
可以先看一下题
根据每日 气温 列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
这题一开始瞅了半天,愣是没看懂啥意思,题目里有句话“对应位置的输出是需要再等待多久温度才会升高超过该日的天数”,主要是理解这句话,大致意思就计算从第二天开始算起,还需要经过多少天,温度才能够达到当前的天数。
比如题中给的例子:
第一天是73,第二天是74,所以在第二天的时候,温度就超过了第一天,所以只经过了1天,所以第一天的输出是1。
再比如:
第三天温度是75,此时需要经过4天,温度才会超过75度(76),所以第三天的输出是4,以此类推。
解析
题目解析完了,现在说一下解题的思路:
1、可以明确的是,最后一天的输出一定是0;
2、是否可以使用动态规划的思想,使用第n天
的输出,计算出第n - 1天
的输出?答案是可以。
3、假设一共有n天,当前天数是m天(m <= n, 当m=n时,result[m] = 0),也就是说我们要求从第m + 1天算起,还要经过多少天温度才会超过第m天的温度。
也就是说,我们要想知道还有多少天温度才会超过第m天的问题,就要判断第m + 1天的温度是否高于第m天,若是的话则为1天。若不是,则需要找到后面几天中第一次高于第m + 1天的温度的天次(比较难理解,算法的核心所在),即T[m + 1 + result[m + 1]] 是否大于第m天的温度,若大于则可求出当前天次的输出,若不是则继续往后寻找。
有了上面这层关系,我们很容易就能推算出解决该问题算法的循环不变式了。
代码
C++代码如下:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
vector<int> result;
result.resize(T.size(), 0);
int nextDay = 0;
int nextDayT = 0;
for (int i = T.size() - 1; i >= 0; --i) {
nextDay = i + 1;
if (nextDay > T.size() - 1) {
result[i] = 0;
continue;
}
nextDayT = T[nextDay];
while (nextDayT <= T[i] && nextDay < T.size() - 1 && result[nextDay] != 0) {
nextDay += result[nextDay];
nextDayT = T[nextDay];
}
result[i] = nextDayT <= T[i] ? 0 : (nextDay - i);
}
return result;
}
};
也有很多同学使用一个栈来求解,一开始我没想明白,也是看了解答后才懂的,可以说用栈的方式去解答该题目更为巧妙,有兴趣的可以自己搜索一下。