739. 每日温度

题目描述

暴力

class Solution {public int[] dailyTemperatures(int[] temperatures) {int n = temperatures.length;int[] res = new int[n];for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {if (temperatures[j] > temperatures[i]) {res[i] = j - i;break;}}}return res;}
}
  • 时间复杂度:O(n2)O(n^2)O(n2)
  • 时间复杂度:O(1)O(1)O(1) (忽略res数组)

单调栈

在求数组/队列中 左边(或右边)下一个最大值(或最小值)时,使用单调栈是一个非常不错的解法

复杂版

由于本题目是求数组中“右边第一个比当前元素大”的节点,所以这里采用的单调栈为:

  • 从栈顶到栈低 --> nums[index]单调递增
  • 栈中存的是temperatures下标i

思路:

  1. 遍历 temperaturestemperaturestemperatures 中所有元素,设当前下标为 iii;
  2. 若当前stack为空,则直接将iii入栈,就完事了;
  3. 否则,若以当前栈顶元素(由于栈中存放的是下标,其实是temperatures[stack.peek()]temperatures[stack.peek()]temperatures[stack.peek()]) <= 当前元素temperatures[i]temperatures[i]temperatures[i],则不会破坏单调性,直接将 i 入栈,即可;
  4. 否则,若栈顶元素(同3解释) > 当前元素temperatures[i]temperatures[i]temperatures[i],此时“单调性”被破坏,需要弹栈维护“单调性”
    • 若当前栈非空,且 temperatures[i] > temperatures[stack.peek(),则需要弹栈
    • 此时(单调性失效),当前元素 temperatures[i]temperatures[i]temperatures[i] 是栈中所有使得“单调性失效”元素的 右边第一个比它大的节点,则需要在弹栈时在 resresres 中记录之,即 res[index] = i - index;

两点注意

  1. 栈中存放的是下标 iii,比较时应该是 temperatures[i]<=temperatures[top]temperatures[i] <= temperatures[top]temperatures[i]<=temperatures[top],而不是 temperatures[i]<=toptemperatures[i] <= toptemperatures[i]<=top;
  2. 在弹栈维护单调性时(while循环中),循环条件必须为 temperatures[i] > temperatures[stack.peek()],而不是 temperatures[i] > temperatures[top]

    此时,弹栈后栈顶元素是动态变化的!!!

class Solution {public int[] dailyTemperatures(int[] temperatures) {if (temperatures.length < 1) return new int[]{};int[] res = new int[temperatures.length];// 从栈顶到栈低 --> nums[index]单调递增// 栈中存的是temperatures下标iDeque<Integer> stack = new LinkedList<>();for (int i = 0; i < temperatures.length; i++) {if (stack.isEmpty()) {stack.push(i);continue;}int top = stack.peek();// 仍然(非严格)单调增,直接入栈if (temperatures[i] <= temperatures[top]) { // 注意:不是 <= topstack.push(i);} else { // >while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { // 不能temperatures[i] > topint index= stack.pop();// 记录res[index] = i - index;}// 当前元素下标入栈stack.push(i);}}return res;}
}
  • 时间复杂度:O(n)O(n)O(n)
  • 时间复杂度:O(n)O(n)O(n) (忽略res数组)

可见单调栈其实是“用空间换时间”!

精简版

以上代码存在冗余部分,可精简如下:

class Solution {public int[] dailyTemperatures(int[] temperatures) {if (temperatures.length < 1) return new int[]{};int[] res = new int[temperatures.length];// 单调栈:从栈顶到栈低 --> nums[index]单调递增,栈中存的是temperatures下标iDeque<Integer> stack = new LinkedList<>();for (int i = 0; i < temperatures.length; i++) {while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { // 不能temperatures[i] > topint index = stack.pop();res[index] = i - index;  // 记录}// 当前元素入栈stack.push(i); }return res;}
}

时、空复杂度不变。

1019. 链表中的下一个更大节点

题目描述

单调栈

思路:

  • 将链表转化为数组;
  • 然后,同739. 每日温度一样了
/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public int[] nextLargerNodes(ListNode head) {// 将链表转化为数组List<Integer> nums = new ArrayList<>();while (head != null) {nums.add(head.val);head = head.next;}System.out.println(nums);int n = nums.size();int[] res = new int[n];// 单调栈:从栈顶到栈低递增(非严格),栈中存放的是nums的下标Deque<Integer> stack = new LinkedList<>();for (int i = 0; i < n; i++) {if (stack.isEmpty()) {stack.push(i);continue;}if (nums.get(i) <= nums.get(stack.peek())) {stack.push(i);} else {// 维护单调性(其中,栈中存放的是nums的下标)while (!stack.isEmpty() && nums.get(stack.peek()) < nums.get(i)) {System.out.println("--------------");System.out.println("stack = " + stack);// 弹栈并记录int index = stack.poll();// 当前元素是单调栈中需要弹栈单调性的节点的右边第一个更大值res[index] = nums.get(i);System.out.println("i = " + i);System.out.println("index = " + index);}// 当前元素入栈(保证单调增)stack.push(i);}}return res;}
}

参考:

  • 单调栈详解
  • Carl题解

单调栈-leetcode-739. 每日温度相关推荐

  1. 184、【栈与队列】leetcode ——739. 每日温度(C++版本)

    题目描述 参考文章:739. 每日温度 解题思路 (1)暴力法 每次遍历到一个数时,就再开辟一个变量找此数后面第一个大于它的数,找到则添加,没找到则返回0. class Solution {publi ...

  2. 2020-06-11 LeetCode 739 每日温度 C++

    题目:739. 每日温度  根据每日 气温 列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替.  例如,给定一个列表 t ...

  3. leetcode 739. 每日温度 单调栈解法和暴力法及其优化 c代码

    如题: 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高, 请在该位置用 0 来代替.例如,给定一个列表 temperature ...

  4. LeetCode 739. 每日温度(单调栈)

    1. 题目 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temperatu ...

  5. leetcode - 739. 每日温度

    根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表temperatures=[73 ...

  6. Leetcode 739. 每日温度 (每日一题 20211014)

    请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度.如果气温在这之后都不会升高,请在该位置用 0 来代替.示例 1:输入: temperatures = [7 ...

  7. leetcode 栈739. 每日温度

    739. 每日温度 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高的天数.如果之后都不会升高,请输入 0 来代替.例如,给定一个列表 temperatures ...

  8. 【LeetCode】【HOT】739. 每日温度(栈)

    [LeetCode][HOT]739. 每日温度 文章目录 [LeetCode][HOT]739. 每日温度 package hot;import java.util.ArrayDeque; impo ...

  9. 力扣739. 每日温度

    739. 每日温度 - 力扣(LeetCode) (leetcode-cn.com) 暴力 class Solution {public int[] dailyTemperatures(int[] t ...

  10. 单调栈 leetcode整理(二)

    目录 为什么单调栈的时间复杂度是O(n) 496. 下一个更大元素 I 方法一:暴力 方法二:单调栈+哈希表 739. 每日温度 单调栈模版解 优化 503. 下一个更大元素 II 单调栈+循环遍历 ...

最新文章

  1. python3入门(三)字典的使用
  2. 自定义Dialog(一)
  3. 国内首篇云厂商 Serverless 论文入选全球顶会:突发流量下,如何加速容器启动?
  4. sql参数化还是被注入了_SQL注入是什么?
  5. listen函数的第二个参数_JavaScript数组构造from函数
  6. __eq___C ++'and_eq'关键字和示例
  7. Shell生成随机uuid
  8. 带你了解Python炫酷的颜色输出与进度条打印
  9. Ugly Numbers UVA - 136
  10. 【java】io流之字符输出流:java.io.Writer类及子类的子类java.io.FileWriter
  11. 在Win10上安装VC6
  12. CSS3与CSS的区别有哪些?
  13. Windows11 使用IE浏览器
  14. 微信发红包的测试用例功能点
  15. c语言二维数组输入数据,c语言编写程序,把下面的数据输入到一个二维数组中:...
  16. Git暂存区有什么用
  17. 页面滑动与锚点的“完美交互”
  18. 深度学习目标检测数据VisDrone2019(to yolo / voc / coco)---MMDetection数据篇
  19. 计算机基础--计算机组成
  20. MTK平台修改Android动画,Android MTK平台修改开关机动画和开机logo

热门文章

  1. 设计窗口模拟教室座位表java,基于web的考研自习教室座位管理(完整源码+论文全套+教学视频)...
  2. phicomm虚拟服务器怎么设置方法,斐讯(PHICOMM)路由器设置步骤
  3. 安卓手机抓包小程序https请求 (该网站安全证书有问题解决办法)
  4. 淘宝京东苏宁易购:网商时代的角逐
  5. Spark整理:相关名词解释
  6. 【家庭网络】申请安装移动宽带过程及简单建议
  7. 判断邮箱格式是否正确(C#实现正则表达式实现)
  8. Task-conditioned Domain Adaptation for Pedestrian Detection in Thermal Imagery(多光谱行人检测)
  9. 物联网技术在智慧校园中的应用
  10. 一日一技:Python + Excel——飞速处理数据分析与处理