我看单调栈

升华抽象:通过一个双向队列保存迭代过的所有可能是答案的元素,通过一些优先级,贡献,从队列中淘汰掉一些不可能是最终结果的点。
大堆小堆,也是维护所有已经迭代过的元素,只是大堆小堆不考虑元素的顺序,也就是在位置上的先后关系。
动作:新元素与队首队尾比较,刷新队列,刷新答案。

1.单调栈问题一般是一维数组
2.按照某种迭代顺序,把所有迭代到的元素推入栈中。
3.按照某种迭代顺序,元素的结果只和前面的元素有关。
4.按照某种迭代顺序,靠后元素满足某种条件时候优先级会高于前面的元素
也就是如果靠后的这个元素优于靠前的元素,前面的元素就再也不纳入考虑范围,那么可以把前面所有
更劣的元素推出栈。
5.最终栈会呈现出与条件相反的趋势,比如说更大的元素更优,那么栈就是单调递减的。反之亦然。
6.关注元素出栈的时候和入栈的时候
7.维护栈的单调递增,那么栈元素在出来的时候就是遇到比自己小的元素。

作用:使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素

相关leetcode练习题汇总:

  1. 柱状图中最大的矩形(https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
  2. 每日温度 (https://leetcode-cn.com/problems/daily-temperatures/
  3. 下一个更大元素 II (https://leetcode-cn.com/problems/next-greater-element-ii/
  4. 最大矩形 (https://leetcode-cn.com/problems/maximal-rectangle/
  5. 接雨水 (https://leetcode-cn.com/problems/trapping-rain-water/
  6. 股票价格跨度 (https://leetcode-cn.com/problems/online-stock-span/
  7. 滑动窗口最大值 (https://leetcode-cn.com/problems/sliding-window-maximum/
  8. 最大宽度坡 (https://leetcode-cn.com/problems/maximum-width-ramp/
  9. 移掉K位数字 (https://leetcode-cn.com/problems/remove-k-digits/

每日温度:单调栈的简单应用,求元素的下一个更大元素
下一个更大元素 II :数组形式扩展,变为环状数组,将组拼接,假设原来的数组是A,则处理AA‘,A’ = A,A’中的每个元素实际上会对
排在自己前面的元素做一次重复,但是不影响结果。
参考代码:

    public int[] nextGreaterElements(int[] nums) {
        int[] res = new int[nums.length];
        //配置好初始值,找不到更大的元素就默认-1,小技巧哦
        Arrays.fill(res, -1);
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < 2 * nums.length; i++) {
            while (!stack.empty() && nums[stack.peek()] < nums[i % nums.length]) {
                res[stack.pop()] = nums[i % nums.length];
            }
            stack.push(i % nums.length);
        }
        return res;    
    }

接雨水问题,官方共给出四种解法,分别是暴力,动态规划,单调递减栈,双指针。
暴力法没有用到每个点之间的关系,复杂度高。动态规划存储好每个点用到的左右界,但界还是有规律的。
双指针的写法:

    public int trap(int[] height) {
        int left = 0, right = height.length - 1;
        int ans = 0;
        int left_max = 0, right_max = 0;
            while (left <= right) {
                if (left_max < right_max) {
                    if (height[left] >= left_max) {
                        left_max = height[left];
                    } else {
                        ans += (left_max - height[left]);
                    }
                    ++left;
                } else {
                    if (height[right] >= right_max) {
                        right_max = height[right];
                    } else {
                        ans += (right_max - height[right]);
                    }
                    --right;
                }
            }
        return ans;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值