前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >​LeetCode 739:每日温度 Daily Temperatures

​LeetCode 739:每日温度 Daily Temperatures

作者头像
爱写bug
发布2019-08-08 17:39:22
8430
发布2019-08-08 17:39:22
举报
文章被收录于专栏:爱写Bug爱写Bug

根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。

例如,给定一个列表 temperatures=[73,74,75,71,69,72,76,73],你的输出应该是 [1,1,4,2,1,1,0,0]

Given a list of daily temperatures T, return a list such 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 of temperatures T=[73,74,75,71,69,72,76,73], your output should be [1,1,4,2,1,1,0,0].

提示: 气温 列表长度的范围是 [1,30000]。每个气温的值的均为华氏度,都是在 [30,100] 范围内的整数。

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

解题思路:

最容易想到和理解的就是暴力穷举,两个指针,一个指针指向当前温度,第二指针向后遍历找到最近一个比当前温度高的温度,记录两个指针的索引差即可。可以说效率非常低了。

另一种方法是借助栈倒序遍历原数组,存入较高的温度的索引,也很容易理解,时间复杂度为 O(n)。其实现逻辑为:

代码语言:javascript
复制
原数组:[73, 74, 75, 71, 69, 72, 76, 73],指针 i 从末尾向前遍历,返回数组res=[0,0,0,0,0,0,0]

第一次遍历: i = 7, T[i] = 73, stack = []
        栈为空,res[7] = 0 ,73所在索引7入栈。stack = [7]

第二次遍历: i = 6, T[i] = 76, stack = [7]
        栈顶对应索引7的温度T[7]=76,76>73,索引7出栈,此时栈为空,res[6] = 0。索引6入栈,stack = [6]

第三次遍历: i = 5, T[i] = 72, stack = [6]
        栈顶对应索引6的温度T[6]=76,72<76,满足要求,当前索引5入栈。res[5] = 栈顶索引6 - 当前索引5 = 1, stack = [6,5]

第四次遍历: i = 4, T[i] = 69, stack = [6,5]
        栈顶对应索引5的温度T[5]=72,69<72,满足要求,当前索引4入栈。res[4] = 栈顶索引5-当前索引4=1, stack = [6,5,4]

第五次遍历: i = 3, T[i] = 71, stack = [6,5,4]
        栈顶对应索引的温度T[4]=69,71>69,栈顶元素出栈。stack = [6,5]
        栈顶对应索引的温度T[5]=72,满足要求,当前索引3入栈。res[3] = 栈顶索引5-当前索引3=2, stack = [6,5,3]

第六次遍历: i = 2, T[i] = 75, stack = [6,5,3]
        栈顶对应索引的温度T[3]=71,75>71,栈顶元素出栈。stack = [6,5]
        栈顶对应索引的温度T[5]=72,75>72,栈顶元素出栈。stack = [6]
        栈顶对应索引的温度T[6]=76,75<76,满足要求,当前索引2入栈。res[2] = 栈顶索引6-当前索引2=4, stack = [6,2]

第七次遍历: i = 1, T[i] = 74, stack = [6,2]
        栈顶对应的温度T[2]=75,满足要求,当前索引1入栈。res[1] = 2-1=1, stack = [6,2,1]

第八次遍历: i = 0, T[i] = 73, stack = [6,2,1]
        栈顶对应的温度T[1]=74,满足要求,当前索引0入栈。res[0] = 1-0=1, stack = [6,2,1,0]

遍历结束: res = [1,1,4,2,1,1,0,0]

这种方法下,栈存入索引对应的温度值始终按升序排列,当栈为空时,证明当前温度为 从该温度向后的所有温度里 最大的。

Java:

代码语言:javascript
复制
class Solution {
    public int[] dailyTemperatures(int[] T) {
        int len=T.length;
        int[] res = new int[len];
        Stack<Integer> stack = new Stack<>();//初始化栈
        for (int i = len - 1; i >= 0; i--) {
            while (!stack.isEmpty() && T[stack.peek()] <= T[i]) {
                stack.pop();
            }
            if (stack.isEmpty()) res[i] = 0;
            else res[i] = stack.peek() - i;
            stack.push(i);
        }
        return res;
    }
}

事实上就这道题而言这并不是一个好方法,因为提示已经明确规定了数据范围:

列表长度的范围是 [1,30000]。每个气温的值的均为华氏度,都是在 [30,100] 范围内的整数。

最多30000个数据量,数据量很,入栈出栈,获取栈顶元素,判断栈是否空,在数据量很少的情况下这些函数反复调用,相对就占用了很多运行时间,其最终评测运行总时间为 109 ms。那么如何优化?

由于所有数据值的范围均在30到100之间,那么意为着按升序排列温度的栈的大小 最大不会超过71(因为从30到100只有71个元素)。那就可以不用栈这个需要反复调用函数的数据结构。直接用长度为71的数组顺序存入索引即可,定义一个指针,索引减一代替出栈,索引加一并赋值代替入栈,索引是否溢出代替判断栈是否为空,无虚函数调用。

优化后:

总运行时间为 4ms,降低了105毫秒

代码语言:javascript
复制
class Solution {
    public int[] dailyTemperatures(int[] T) {
        int len = T.length;
        int[] res = new int[len], stack = new int[71];
        int index = -1;
        for (int i = len - 1; i >= 0; i--) {
            while (index >= 0 && T[stack[index]] <= T[i]) {
                index--;
            }
            if(index >= 0) res[i] = stack[index] - i;
            stack[++index] = i;
        }
        return res;
    }
}

Python:

python并没有队列、栈这种数据结构,因为数组就可以做到先进先出、后进先出等操作。

代码语言:javascript
复制
class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        tLen = len(T)
        stack = []
        res = [0] * tLen
        for i in range(tLen - 1, -1, -1):
            while stack and T[i] >= T[stack[-1]]:
                stack.pop()
            if stack: res[i] = stack[-1] - i
            stack.append(i)
        return res
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱写Bug 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解题思路:
  • Java:
  • 优化后:
  • Python:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档