[菜鸟训练]739. 每日温度

这篇博客介绍了如何解决一个关于气温列表的问题,即根据输入的每日气温,计算出要等待多少天才能遇到更高气温。博主提出了两种解题方法,一种是两层循环的暴力解法,时间复杂度为O(n^2),另一种是使用单调栈,时间复杂度为O(n)。通过示例解释了算法的工作原理,并提供了具体的Java实现代码。

题目描述:

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

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

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

题目解读:

题目的意思是给你一个气温列表,让你根据给出的气温列表得到一个新的列表,新列表内存的值代表的意思是为当前下标对应的气温列表中的温度,要过几天能遇到比自己温度高的温度。
比如题目中给出的例子:
temperatures = [73, 74, 75, 71, 69, 72, 76, 73]
ans = [1, 1, 4, 2, 1, 1, 0, 0]

ans[1]=1的意思是73这个温度至少要过1天才能遇到比自己温度高的温度,即遇到了74.
ans[2]=1的意思是74这个温度至少要过1天才能遇到比自己温度高的温度,即遇到了75.
ans[3]=4的意思是75这个温度至少要过4天才能遇到比自己温度高的温度,即遇到了76.
…以此类推

解题思路:

方法一: 直接两层循环暴力,根据题目要求我们只需要找当前之后存不存在比自己温度高的,若不存在,该温度对应的ans数组则为0;若存在,选取第一个,ans数组就是温度高的这天减去当前的天,即温度高的下表j减去当前的下标i。
时间复杂度O(n^2) 空间复杂度O(n)

方法二: 单调递减栈,该栈中存的数据是温度对应的下标,并且是单调递减的,即从栈底到栈顶的下标对应的温度列表中的温度依次递减。造好栈之后,我们去遍历温度列表,如果栈是空的,或者当前下标对应的温度比栈顶元素对应的温度还要小,我们就让当前下标入栈;如果栈不为空,且当前下标对应得温度比栈顶高,那说明栈顶元素已经找到了比自己温度高的温度,我们进而更新对应的ans数组的值,
ans[取出的栈顶元素的值]=当前找到的高温的下标-取出的栈顶元素的值
注意我们这里栈中存取的是和温度相对应得下标。

此时操作完成后,若栈不空,我们不急将当前温度对应的下标入栈,我们接着判断当前栈顶元素是否小于当前元素,若小于则重复上述操作。直到遇到栈空或者当前下标对应得温度比栈顶元素对应得温度小,我们将当前下标入栈。
时间复杂度O(n) 空间复杂度O(n)

代码:

public class LC739 {
    //暴力
    public int[] dailyTemperatures(int[] T) {
        int[] ans = new int[T.length];
        for (int i = 0; i < T.length - 1;i++){
            for (int j = i + 1; j < T.length; j++){
                if (T[j] > T[i]){
                    ans[i] = j - i;
                    break;
                }
            }
        }
        return ans;
    }

    //存下标的单调栈,单调递减栈,即从栈底到栈顶的下标对应的温度列表中的温度依次递减
    //时间复杂度O(N) 空间复杂度O(N)
    public int[] dailyTemperatures1(int[] T){
        int[] ans = new int[T.length];
        //造一个栈,用来存储当前还未遇到比自己温度高的温度在温度列表的下标
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < T.length; i++){
            int tmp = T[i];
            //如果栈不空且栈顶元素比当前温度小,则说明栈顶找到了比自己更高的温度
            //我们就可以将其从栈中取出,ans[取出的栈顶元素的值]=当前温度的下标-取出的栈顶元素的值
            while (!stack.isEmpty() && tmp > T[stack.peek()]){
                int pre = stack.pop();
                ans[pre] = i - pre;
            }
            //注意每个元素都要入栈
            stack.push(i);
        }
        return ans;
    }

    public static void main(String[] args) {
        LC739 obj = new LC739();
        int[] T = new int[]{73, 74, 75, 71, 69, 72, 76, 73};
        int[] ans = obj.dailyTemperatures1(T);
        for (int i = 0; i < ans.length; i++){
            System.out.println(ans[i]);
        }
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值