单调栈汇总

单调栈

单调栈是一种特殊的栈结构,其内部元素始终保持单调递增或者单调递减的特性。

  • 单调递增栈:栈内元素从栈底到栈顶是单调递增的。当新元素入栈时,若它小于栈顶元素,则直接入栈;若它大于栈顶元素,就需要不断弹出栈顶元素,直至满足单调递增的条件再入栈。
  • 单调递减栈:栈内元素从栈底到栈顶是单调递减的。当新元素入栈时,若它大于栈顶元素,则直接入栈;若它小于栈顶元素,就需要不断弹出栈顶元素,直至满足单调递减的条件再入栈。

1.每日温度

力扣题目链接(opens new window)

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

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

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

public class Daily_Temperatures {
   public int[] dailyTemperatures2(int[] temperatures) {
            int lens=temperatures.length;//获取温度数组 temperatures 的长度。
            int []res=new int[lens];//创建一个长度为 lens 的数组,用于存储每个温度需要等待的天数,初始值都为 0。
            Deque<Integer> stack=new LinkedList<>();//创建一个双端队列 Deque 作为栈,用于存储温度数组的索引。
            for(int i=0;i<lens;i++){//从索引0开始遍历temperatures。
                while(!stack.isEmpty()&&temperatures[i]>temperatures[stack.peek()]){//对于每个元素,如果栈不为空且当前温度大于栈顶元素对应的温度,则执行以下操作:弹出栈顶元素,并计算结果数组res中该元素对应的值。继续检查栈是否为空以及栈顶元素对应的温度是否小于当前温度,直到栈为空或栈顶元素对应的温度不小于当前温度。
                    res[stack.peek()]=i-stack.peek();//当前索引 i 对应的温度比栈顶元素对应的温度高,所以等待天数就是两者索引的差值。peek() 方法的作用是查看栈顶元素,却不把该元素从栈中移除。
                    stack.pop();//计算完等待天数后,将栈顶元素弹出,继续检查新的栈顶元素,直到栈为空或栈顶元素对应的温度不小于当前温度。
                }
                stack.push(i);//无论是否执行了 while 循环,都将当前索引 i 压入栈中。
            }
            return  res;
        }
}

temperatures = [73, 74, 75, 71, 69, 72, 76, 73]

初始化:

  1. 数组长度lens = temperatures.length = 8

  2. 结果数组res = [0, 0, 0, 0, 0, 0, 0, 0](初始值为0)。

  3. stack = [](空栈)。

逐步执行:

我们将逐步遍历 temperatures 数组,并按照代码逻辑操作栈和结果数组。

第1天(索引 i = 0):
  • 当前温度:temperatures[0] = 73

  • 栈为空,直接将索引0压入栈:stack = [0]

第2天(索引 i = 1):
  • 当前温度:temperatures[1] = 74

  • 栈不为空,且 74 > temperatures[stack.peek()] = temperatures[0] = 73

    • 弹出栈顶元素:stack.pop(),栈顶索引为0。

    • 计算等待天数:res[0] = i - stack.peek() = 1 - 0 = 1

    • 更新结果数组:res = [1, 0, 0, 0, 0, 0, 0, 0]

  • 将当前索引1压入栈:stack = [1]

第3天(索引 i = 2):
  • 当前温度:temperatures[2] = 75

  • 栈不为空,且 75 > temperatures[stack.peek()] = temperatures[1] = 74

    • 弹出栈顶元素:stack.pop(),栈顶索引为1。

    • 计算等待天数:res[1] = i - stack.peek() = 2 - 1 = 1

    • 更新结果数组:res = [1, 1, 0, 0, 0, 0, 0, 0]

  • 将当前索引2压入栈:stack = [2]

第4天(索引 i = 3):
  • 当前温度:temperatures[3] = 71

  • 栈不为空,但 71 < temperatures[stack.peek()] = temperatures[2] = 75

  • 直接将当前索引3压入栈:stack = [2, 3]

第5天(索引 i = 4):
  • 当前温度:temperatures[4] = 69

  • 栈不为空,但 69 < temperatures[stack.peek()] = temperatures[3] = 71

  • 直接将当前索引4压入栈:stack = [2, 3, 4]

第6天(索引 i = 5):
  • 当前温度:temperatures[5] = 72

  • 栈不为空,且 72 > temperatures[stack.peek()] = temperatures[4] = 69

    • 弹出栈顶元素:stack.pop(),栈顶索引为4。

    • 计算等待天数:res[4] = i - stack.peek() = 5 - 4 = 1

    • 更新结果数组:res = [1, 1, 0, 0, 1, 0, 0, 0]

  • 栈不为空,且 72 > temperatures[stack.peek()] = temperatures[3] = 71

    • 弹出栈顶元素:stack.pop(),栈顶索引为3。

    • 计算等待天数:res[3] = i - stack.peek() = 5 - 3 = 2

    • 更新结果数组:res = [1, 1, 0, 2, 1, 0, 0, 0]

  • 栈不为空,但 72 < temperatures[stack.peek()] = temperatures[2] = 75

  • 将当前索引5压入栈:stack = [2, 5]

第7天(索引 i = 6):
  • 当前温度:temperatures[6] = 76

  • 栈不为空,且 76 > temperatures[stack.peek()] = temperatures[5] = 72

    • 弹出栈顶元素:stack.pop(),栈顶索引为5。

    • 计算等待天数:res[5] = i - stack.peek() = 6 - 5 = 1

    • 更新结果数组:res = [1, 1, 0, 2, 1, 1, 0, 0]

  • 栈不为空,且 76 > temperatures[stack.peek()] = temperatures[2] = 75

    • 弹出栈顶元素:stack.pop(),栈顶索引为2。

    • 计算等待天数:res[2] = i - stack.peek() = 6 - 2 = 4

    • 更新结果数组:res = [1, 1, 4, 2, 1, 1, 0, 0]

  • 栈为空,将当前索引6压入栈:stack = [6]

第8天(索引 i = 7):
  • 当前温度:temperatures[7] = 73

  • 栈不为空,但 73 < temperatures[stack.peek()] = temperatures[6] = 76

  • 将当前索引7压入栈:stack = [6, 7]

最终结果:

  • 遍历结束后,栈中剩余的索引对应的温度没有更高的温度,因此它们的结果值保持为0。

  • 最终结果数组:res = [1, 1, 4, 2, 1, 1, 0, 0]

2.下一个更

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值