一天一道算法题(29):单调栈

739. 每日温度

文章目录

给定一个整数数组 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]

思路

- 暴力

  • 空间复杂度O(1)(在力扣里面使用原数组记录不算入空间复杂度),时间复杂度O(n)

  • 嵌套循环,第一层遍历每一个元素,第二层循环遍历该元素后面的每一个元素,如果发现存在更大值,就break,把结果写入数组,这里我为了避免超时,使用了原数组直接修改值,最后返回原数组的方式,可惜还是超时了,没有办法,所以我们要使用时间复杂度更低的办法了

go 复制代码
func dailyTemperatures(temperatures []int) []int {
    for i := 0; i < len(temperatures); i++ {
        flag := 0
        var j int
        for j = i+1; j < len(temperatures); j++ {
            if temperatures[j] > temperatures[i] {
                flag = 1
                break
            }
        }
        if flag == 1 {
            temperatures[i] = j-i
        } else {
            temperatures[i] = 0
        }
    }
    return temperatures
}

- 单调栈

  • 我们维护一个单调递减栈,这个单调递减栈的操作是这样的

  • 第一种情况是栈为空或者当前温度小于等于栈顶温度,这符合递减栈的规则,所以直接将当前下标入栈。

  • 第二种情况是当前温度大于栈顶温度,这说明栈顶元素已经找到了它需要的更高温度,于是进入内层循环,只要栈不为空且当前温度继续大于栈顶温度,就反复计算天数差并写入数组,同时将栈顶弹出。内层循环结束后,当前温度也要作为新的栈顶元素入栈,以便后续比较。

  • 当整个数组遍历完成后,栈中可能还会剩余一些下标,这些下标对应的日子再也没有遇到更高的温度,根据题目要求需要将它们对应的位置赋值为零。最后返回这个被修改过的数组,就是最终答案

- 图文解析

go 复制代码
func dailyTemperatures(temperatures []int) []int {
    //单调栈
    stack := []int{}
    for i, v := range temperatures {
        //当前元素大于栈顶元素的时候,弹出,直到符合单调栈的情况
        for len(stack) != 0 && v > temperatures[stack[len(stack)-1]] {
            temperatures[stack[len(stack)-1]] = i-stack[len(stack)-1]
            stack = stack[:len(stack)-1]
        }
        //对当前元素入栈
        stack = append(stack, i)
    }
    //剩余的元素也要出栈,对于剩余的元素把结果直接记录为0
    for _, v := range stack {
        temperatures[v] = 0
        stack = stack[:len(stack)-1]
    }
    return temperatures
}

结语

本文是 《算法题目解析系列》 的第 29 篇,本系列将持续更新,每篇都提供清晰的思路与编程语言实现。欢迎关注,第一时间获取更新。如果你有想看的题目,也可以在评论区留言告诉我。

相关推荐
萧鼎1 小时前
2026新库实测:sbxloop 1.5.24 让 AI Agent 在 Docker 沙箱中安全自治,告别环境混乱
人工智能·python·开源·开发工具·ai agent
XR1234567881 小时前
医院移动医护零漫游无线网络选型指南
java·后端·struts
干到60岁退休的码农1 小时前
13.构建登录接口响应数据
java·spring boot·mybatis
栀椩1 小时前
CODrone 无人机航拍车辆检测
pytorch·python·yolo
苦瓜小生1 小时前
【前端】【力扣与手撕】十天带你刷完前端算法与手撕,全是最简单好记的最优解法!day4
前端·数据结构·算法·leetcode·面试
会飞的拖把2 小时前
Python序列详解:列表、元组、字符串的通用操作(超详细版)
开发语言·windows·python
水巷石子2 小时前
学习langChain4j的第二天,体验springBoot中的starter
java·spring boot·学习·spring·langchain4j
2601_962283882 小时前
如何通过python控制nbiot
python·串口通信·数据传输·nb-iot·at命令
ly76892 小时前
Spring Bean生命周期全流程:从BeanDefinition到销毁
java·后端·spring·bean生命周期·beandefinition·初始化回调