【LeetCode】每日温度 [M](单调栈)

给定一个整数数组temperatures表示每天的温度,返回一个数组answer,其中answer[i]是指对于第i天,下一个更高温度出现在几天后。使用单调栈解决此问题,遍历数组并维护一个自底向上的温度栈,找到每个元素右边的第一个比它大的元素距离。
摘要由CSDN通过智能技术生成

739. 每日温度 - 力扣(LeetCode)

一、题目

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

示例 2:​​​​​​​

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例 3:​​​​​​​

输入: temperatures = [30,60,90]
输出: [1,1,0]

提示:​​​​​​​

  • 1 <= temperatures.length <= 105
  • 30 <= temperatures[i] <= 100

二、代码

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        // 存储每一个位置距离自己右边最近的比自己大的数有多远
        // ans[i]:temperatures[i]到自己右边最近的比自己大的数字的距离是ans[i]
        // 默认为0,这样如果没有找到右边有比自己大的就说明温度在以后不会升高了
        int[] ans = new int[n];
        // 过滤无效参数
        if (temperatures == null || temperatures.length == 0) {
            return ans;
        }
        // 单调栈,按照自底向上是从大到小排列,为了找每一个数右边比自己大的最近的数是什么
        // 链表中存储的是下标,同一个链表中的下标指向的值都是一样大的
        Stack<List<Integer>> stack =  new Stack<>();
        // 遍历数组
        for (int i = 0; i < n; i++) {
            // 如果栈顶不为空,并且当前遍历到的数大于栈顶的数,说明如果插入temperatures[i]就会破坏单调栈结构
            // 这里用循环,如果一直会破坏单调栈结构,就一直弹出收集答案
            while (!stack.isEmpty() && temperatures[stack.peek().get(0)] < temperatures[i]) {
                // 弹出栈顶数据,来收集被弹出的位置右边比自己大的且最近的数字的信息
                List<Integer> topList = stack.pop();
                // 链表中存储的是下标,他们指向的值都是一样的
                for (Integer index : topList) {
                    // i就是index右边比自己大且离自己最近的数字的下标
                    // 他们的距离就是i - index
                    ans[index] = i - index;
                }
            }

            // 如果栈不为空,并且与栈顶数字相等
            if (!stack.isEmpty() && temperatures[stack.peek().get(0)] == temperatures[i]) {
                // 有重复值的情况,直接将i加入到栈顶链表中即可
                stack.peek().add(i);
            // 栈为空,或者i没有破坏单调栈结构(自底向上从大到小),就将i作为一个新的节点压入栈中    
            } else {
                // 创建新的链表
                List<Integer> nodeList = new ArrayList<>();
                // 将i加入链表
                nodeList.add(i);
                // 将链表压入栈中
                stack.push(nodeList);
            }
        }

        // 返回答案
        return ans;
    }
}

三、解题思路 

这道题关键就是能联想到单调栈,将这个问题的本质抽象出来,就能发现其实本质就是一个单调栈问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值