[leetcode] Daily Temperatures

Given a list of daily temperatures, produce a list that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. If there is no future day for which this is possible, put 0 instead.

For example, given the list temperatures = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0].

Note: The length of temperatures will be in the range [1, 30000]. Each temperature will be an integer in the range [30, 100].


分析:题目意思也很明确,翻译一下就是给定一个数组,对于每个数组元素,要找到比它更大的那个数字与当前元素的距离。
       很容易想到用一个二层循环,如果找到了个比他大的就返回距离并且break,但是这样时间复杂度时O(n^2),显然不是好的,不过也写一下实现,代码如下:
 1 class Solution {
 2     public int[] dailyTemperatures(int[] temperatures) {
 3         int n = temperatures.length;
 4         int[] ans = new int[n];
 5         for ( int i = 0 ; i < n - 1; i ++ ){
 6             for ( int j = i+1 ; j < n  ; j ++ ){
 7                 if ( temperatures[j] > temperatures[i] ) {
 8                     ans[i] = j-i;
 9                     break;
10                 }
11             }
12         }
13         return ans;
14     }
15 }

      运行时间231ms,击败了18.35%的人。很显然是个很差的算法。


 第二个思路:想到既然是要找大小的数字,肯定要联想到stack,因为stack很容易做大小的比较。刚开始我想的是用栈保存温度的值,然后循环比较当前温度与栈顶温度,但是这样发现无法记录栈底温度的天数。于是换一个思路,用栈来保存日期,这样就可以解决栈底无法记录天数的问题了。代码如下:
 1 class Solution {
 2     public int[] dailyTemperatures(int[] temperatures) {
 3         //第二种方法,用栈解决
 4         int[] ans = new int[temperatures.length];
 5         Stack<Integer> stack = new Stack<>();
 6         for ( int i = 0 ; i < temperatures.length ; i ++ ){
 7             while ( !stack.isEmpty() && temperatures[i] > temperatures[stack.peek()] ){  //当栈非空并且当前温度大于栈顶天温度
 8                 int day = stack.pop();
 9                 ans[day] = i-day;
10             }
11             stack.push(i);
12         }
13         return ans;
14     }
15 }

      运行时间52ms,击败了76.35%的人。总结一下:发现用二层循环找大小的问题,都可以从栈的角度来考虑。之前也做过栈的相关题目,典型的括号匹配问题,后续表达式问题,等等。以后会对类似的题目进行一下总结。

原文地址:https://www.cnblogs.com/boris1221/p/9294526.html