LeetCode Hot100题 第739题 每日温度

先贴一下题目描述:

请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

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

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

方法一

暴力法就不介绍了,大家应该都想得到,方法一其实可以看做是暴力法的优化,在暴力法中,我们从数组左边开始遍历,但我们仔细阅读题目之后可以发现,从右往左遍历可以明显的减少遍历次数,因为我们每次遍历都会记录升温所需的天数,我们可以利用这个天数作为跳板,去寻找更高的温度。

这样看文字可能太抽象了,我们来看个图

42
43
44
45
48

因为我们是从右往左遍历,在遍历到45时,结果集里已经存放了44升温所需要的的天数3天,当我们考虑45处升温所需要的的温度时,我们先看他后一位的温度,如果比他大那直接将下标差放入结果集,但如果比他小的话,我们就读取结果集里相应位置的值,直接跳过43和42,到达48的位置

话不多说,直接上代码吧

public int[] dailyTemperatures(int[] T) {
    int length = T.length;
    int[] result = new int[length];
    for (int i = 0; i < length; i++) {
        int current = T[i];
        if (current < 100) {
            for (int j = i + 1; j < length; j++) {
                if (T[j] > current) {
                    result[i] = j - i;
                    break;
                }
            }
        }
    }

    return result;
}

方法二

单调栈法:引用自LeetCode官方题解

作者:LeetCode-Solution

链接:https://leetcode-cn.com/problems/daily-temperatures/solution/mei-ri-wen-du-by-leetcode-solution/

可以维护一个存储下标的单调栈,从栈底到栈顶的下标对应的温度列表中的温度依次递减。如果一个下标在单调栈里,则表示尚未找到下一次温度更高的下标。

正向遍历温度列表。对于温度列表中的每个元素 T[i],如果栈为空,则直接将 i 进栈,如果栈不为空,则比较栈顶元素 prevIndex 对应的温度 T[prevIndex] 和当前温度 T[i],如果 T[i] > T[prevIndex],则将 prevIndex 移除,并将 prevIndex 对应的等待天数赋为 i - prevIndex,重复上述操作直到栈为空或者栈顶元素对应的温度小于等于当前温度,然后将 i 进栈。

为什么可以在弹栈的时候更新 ans[prevIndex] 呢?因为在这种情况下,即将进栈的 i 对应的 T[i] 一定是 T[prevIndex] 右边第一个比它大的元素,试想如果 prevIndex 和 i 有比它大的元素,假设下标为 j,那么 prevIndex 一定会在下标 j 的那一轮被弹掉。

由于单调栈满足从栈底到栈顶元素对应的温度递减,因此每次有元素进栈时,会将温度更低的元素全部移除,并更新出栈元素对应的等待天数,这样可以确保等待天数一定是最小的。

以下用一个具体的例子帮助读者理解单调栈。对于温度列表 [73,74,75,71,69,72,76,73],单调栈 stack 的初始状态为空,答案 ans的初始状态是 [0,0,0,0,0,0,0,0],按照以下步骤更新单调栈和答案,其中单调栈内的元素都是下标,括号内的数字表示下标在温度列表中对应的温度。

当 i=0 时,单调栈为空,因此将 0 进栈。

    stack=[0(73)]
    ans=[0,0,0,0,0,0,0,0]

当 i=1时,由于 74 大于 73,因此移除栈顶元素 0,赋值 ans[0]:=1−0,将 111 进栈。

    stack=[1(74)]

    ans=[1,0,0,0,0,0,0,0]

当 i=2 时,由于 75 大于 74,因此移除栈顶元素 1,赋值 ans[1]:=2−1,将 2 进栈。

    stack=[2(75)]

    ans=[1,1,0,0,0,0,0,0]

当 i=3 时,由于 71 小于 75,因此将 3 进栈。

    stack=[2(75),3(71)]

    ans=[1,1,0,0,0,0,0,0]

当 i=4 时,由于 69 小于 71,因此将 4 进栈。

    stack=[2(75),3(71),4(69)]

    ans=[1,1,0,0,0,0,0,0]

当 i=5 时,由于 72 大于 69 和 71,因此依次移除栈顶元素 4 和 3,赋值 ans[4]:=5−4 和 ans[3]:=5−3,将 5 进栈。

    stack=[2(75),5(72)]

    ans=[1,1,0,2,1,0,0,0]

当 i=6 时,由于 76 大于 72 和 75,因此依次移除栈顶元素 5 和 2,赋值 ans[5]:=6−5 和 ans[2]:=6−2,将 6 进栈。

    stack=[6(76)]

    ans=[1,1,4,2,1,1,0,0]

当 i=7 时,由于 73 小于 76,因此将 7 进栈。

    stack=[6(76),7(73)]

    ans=[1,1,4,2,1,1,0,0]
class Solution {
    public int[] dailyTemperatures(int[] T) {
        int length = T.length;
        int[] ans = new int[length];
        Deque<Integer> stack = new LinkedList<Integer>();
        for (int i = 0; i < length; i++) {
            int temperature = T[i];
            while (!stack.isEmpty() && temperature > T[stack.peek()]) {
                int prevIndex = stack.pop();
                ans[prevIndex] = i - prevIndex;
            }
            stack.push(i);
        }
        return ans;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值