leetcode739 - Daily Temperatures - medium
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].
Stack. O(n)。
brute force:O(n^2),每个点就向右再遍历一次,遇到的第一个更大的点就取坐标差为答案。
突破口:从右到左计算答案,对一串……AB的排列,如果A比B大,那么B就对前面的…...没有任何影响了,没必要保留信息。如果保留一个数据结构,能够记下一连串逐渐增大的关键有效数字,那对…...部分就可以一个个跳跃去查了,时间复杂度好很多。因为从右到左遍历,这个数据结构要先取到刚加入的信息,所以用stack。
步骤:
1.开一个stack记录一路过来的下标。(因为temp值可以通过下标直接取到,不需要另开stack)
2.从右向左遍历:
3.->如果看到当前temp < peek.temp,说明peek就是我要找的那个第一个温暖天,下标差即答案。记得把自己推入stack更新信息。
4.->如果看到当前temp >= peek.temp,说明peek还没能满足我,我要把这个peek pop掉,取到peek后面更大的值(因为你这一套实现下来自洽完成pop出的东西越来越大这一套的)。while循环到找到更大值了,这个下标就是你要的第一个温暖天了。(corner case: stack被你弄空了就说明后面没有合格天得填0)。记得把自己推入stack更新信息。(刚才那些都被pop掉了没关系,因为我比他们大,他们对我接下来要接着往左遍历的数没贡献了。我保留了右边比我还大的数就足够了)
细节:
1.精简stack个数。不要又开一个temps又开一个idxs,因为输入数组将它们关联,你这样就是冗余信息了。
实现:
class Solution { public int[] dailyTemperatures(int[] temperatures) { // store the index Stack<Integer> stack = new Stack<>(); int[] ans = new int[temperatures.length]; stack.push(temperatures.length - 1); for (int i = temperatures.length - 2; i >= 0; i--) { int temp = temperatures[i]; if (temp < temperatures[stack.peek()]) { ans[i] = stack.peek() - i; stack.push(i); } else { while (!stack.isEmpty() && temp >= temperatures[stack.peek()]) { stack.pop(); } ans[i] = stack.isEmpty() ? 0 : stack.peek() - i; stack.push(i); } } return ans; } }