【随想录】Day59—第十章 单调栈part02


题目1:下一个更大元素II

  • 题目链接:

1- 思路

模式理解:

  • 模式1:下一个更大 ——> 单调栈
  • 模式2:环形数组 ——> 取模代替成环的过程

思路
1- 数据结构

  • 创建单调栈
  • 结果集 int 数组

2- 遍历环形数组,利用 2*len 取模实现

  • **2-1 遍历:**i 从 1 遍历到 2*len
  • 2-2 当前元素 <= 栈顶:此时入栈即可
  • 2-3 当前元素 > 栈顶:收集结果
    • 利用 while 两个条件来一直收集结果 ①st不为空②当前元素大于栈顶
    • 收集结果
    • st 进行 pop

2- 题解

⭐ 下一个更大元素 II——题解思路

在这里插入图片描述

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        // 1. 数据结构
        int len = nums.length;
        int[] res = new int[len];
        Arrays.fill(res,-1);

        // 2. 单调栈
        Stack<Integer> st = new Stack<>();
        st.push(0);
        for(int i = 1 ; i < len*2 ;i++){
            // 小于等于
            if(nums[i%len]<= nums[st.peek()]){
                st.push(i%len);
            }else{
                while(!st.isEmpty() && nums[i%len] > nums[st.peek()]){
                    res[st.peek()] = nums[i%len];
                    st.pop(); 
                }
                st.push(i%len);
            }
        }
        
        return res;
    }
}

题目2:42. 接雨水


1- 思路

利用单调栈,在当前元素大于栈顶元素的时候收集结果

  • nums[i] > nums[st.peek()] 时 收集结果
  • 收集结果思路:当前元素大,证明是凹槽的右侧 第一高的元素,找到凹槽左侧比凹槽高的柱子即可,也就是栈中第二个柱子的高度
  • ① 获取中间元素 mid = st.pop()——> ② 此时 st.peek() 就是左侧高的柱子 ;nums[i]为右侧高柱子;当前元素为 nums[mid]
  • ——> ③ 处理逻辑 h = Math.min(st.peek(),nums[mid])
  • ——> width = i - st.peek() - 1
  • ——> 面积为 h * width

** 实现思路**

  • 1- 数据结构
    • 结果数组:int res = 0
    • 单调栈:Stack<Integer> st = new Stack<>(),初始化填入 0
  • 2- 遍历
    • 2-1 遍历顺序i1 遍历到 nums.length
    • 2-2 当前元素 <= st.peek(): 直接入栈
    • 2-3 当前元素 > st.peek() :处理逻辑
      • 右侧高柱子:当前元素为
      • 凹槽元素:定义 mid 获取当前 st.pop() 为凹槽元素
      • 左侧高元素:st.peek() 为左侧高元素
      • height = Math.min(height[left], height[i]) - height[mid]
      • width = i - st.peek - 1
      • 结果收集: res+= height * width

2- 题解

⭐ 接雨水 ——题解思路

在这里插入图片描述

class Solution {
    public int trap(int[] height) {
        // 数据结构
        int len = height.length;
        int res = 0;
        Stack<Integer> st = new Stack<>();

        st.push(0);

        // 遍历
        for(int i = 1 ; i < len ;i++){
            if(height[i] <= height[st.peek()]){
                st.push(i);
            }else{
                while(!st.isEmpty() && height[i] > height[st.peek()]){
                    int mid = st.pop();
                    if(!st.isEmpty()){
                        int left = st.peek();
                        int h = Math.min(height[left],height[i])-height[mid];
                        int w = i - left -1;
                        int hold = h*w;
                        if(hold>0){
                            res+=hold;
                        }
                    }
                }
                st.push(i);
            }

        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值