(leetcode)力扣100 72每日温度(栈)

题目

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

数据范围

1 <= temperatures.length <= 105

30 <= temperatures[i] <= 100

测试用例

示例1

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

示例2

java 复制代码
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例3

java 复制代码
输入: temperatures = [30,60,90]
输出: [1,1,0]

题解1(博主题解,时空On)

java 复制代码
import java.util.Deque;
import java.util.LinkedList;

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        // 创建一个单调栈,栈里的元素是整型数组 int[]
        // 约定:int[0] 存温度值,int[1] 存该温度对应的下标(第几天)
        Deque<int[]> deque = new LinkedList<>();
        int len = temperatures.length;
        
        // 结果数组,Java 默认会将里面所有元素初始化为 0
        int res[] = new int[len];
        
        // 循环开始前,先把第 0 天的数据打包压入栈中作为初始参照物
        deque.push(new int[]{temperatures[0], 0});
        
        // 因为第 0 天已经处理了,所以从第 1 天开始遍历
        for (int i = 1; i < len; i++) {
            // 当栈不为空,且【今天的温度】大于【栈顶存的过去的温度】时
            // deque.peek()[0] 取出的就是栈顶那个 int[] 里的温度值
            while (!deque.isEmpty() && temperatures[i] > deque.peek()[0]) {
                // 获取栈顶元素(但不从栈里踢出去)
                int t[] = deque.peek();
                // t[1] 是过去那一天的下标,i 是今天的下标
                // i - t[1] 就是这两天之间相隔的天数(也就是等待的天数)
                res[t[1]] = i - t[1];
                // 既然过去的那一天已经等到了更高的温度,就把它从栈里踢出去
                deque.poll();
            }
            // 无论刚才有没有发生出栈操作,今天的数据都要打包进栈,等着未来的某一天来清算
            deque.push(new int[]{temperatures[i], i});
        }
        
        // 遍历结束后,还在栈里的那些天数,意味着直到最后也没等到升温。
        // 因为 res 数组默认全是 0,所以不需要管它们了,直接返回结果即可。
        return res;
    }
}

题解2(官解,时空同上)

java 复制代码
import java.util.Deque;
import java.util.LinkedList;

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int length = temperatures.length;
        int[] ans = new int[length];
        
        // 创建一个单调栈,栈里【只存下标】(Integer 类型)
        Deque<Integer> stack = new LinkedList<Integer>();
        
        // 直接从第 0 天开始统一遍历,不需要在循环外提前处理第 0 天
        for (int i = 0; i < length; i++) {
            // 记录当天的温度
            int temperature = temperatures[i];
            
            // 当栈不为空,且【今天的温度】大于【栈顶下标所对应的历史温度】时
            // temperatures[stack.peek()]:通过栈顶存的下标,去原数组里查到当时的温度
            while (!stack.isEmpty() && temperature > temperatures[stack.peek()]) {
                // pop() 方法会直接把栈顶的下标弹出来,并赋值给 prevIndex
                // 这里一步到位,代替了你代码里的 peek() + poll() 两步操作
                int prevIndex = stack.pop();
                
                // 计算天数差,存入结果数组对应的位置
                ans[prevIndex] = i - prevIndex;
            }
            // 今天还没找到更高的温度(或者已经把历史比它低的都清算了)
            // 把今天的下标压入栈中,等待未来的某一天
            stack.push(i);
        }
        
        return ans;
    }
}

思路

这道题就是一道很简单的栈应用问题了,由于数据范围是10的五次方,用暴力必然TLE,所以我们需要考虑到使用栈一次处理,这道题的栈应用方法很简单没有什么说的,博主的方法栈存的是int数组,既存数据又存下标,其实没必要这样,直接只存下标就行了,就是官解的写法。

相关推荐
炒鸡菜666几秒前
程序人生-Hello’s P2P
c语言·程序人生·职场和发展
weixin_4588726110 分钟前
东华复试OJ二刷复盘2
算法
Charlie_lll11 分钟前
力扣解题-637. 二叉树的层平均值
算法·leetcode
爱淋雨的男人21 分钟前
自动驾驶感知相关算法
人工智能·算法·自动驾驶
wen__xvn32 分钟前
模拟题刷题3
java·数据结构·算法
滴滴答滴答答1 小时前
机考刷题之 6 LeetCode 169 多数元素
算法·leetcode·职场和发展
圣保罗的大教堂1 小时前
leetcode 1980. 找出不同的二进制字符串 中等
leetcode
Neteen1 小时前
【数据结构-思维导图】第二章:线性表
数据结构·c++·算法
礼拜天没时间.1 小时前
力扣热题100实战 | 第25期:K个一组翻转链表——从两两交换到K路翻转的进阶之路
java·算法·leetcode·链表·递归·链表反转·k个一组翻转链表
Swift社区2 小时前
LeetCode 400 第 N 位数字
算法·leetcode·职场和发展