单调栈最后一天

目录

84.柱状图中最大的矩形

看到题目时的第一想法

看到代码随想录的想法

实现时出现的困难


84.柱状图中最大的矩形

力扣题目链接(opens new window)

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

在该柱状图中,能够勾勒出来的矩形的最大面积。

看到题目时的第一想法

想到用单调栈,但是不知道怎么做

看到代码随想录的想法

单调栈,单调减,若遇到比栈顶小的元素则出栈

以栈顶为基准来算最大面积,找左边第一个比自己小的下标,遍历过的元素,栈顶第二个元素

                                                找右边第一个比自己小的下标,当前遍历到的元素(若比栈顶小)

   

两者下标之差值-1,就是宽度,当前栈顶就是高度

实现时出现的困难

        开始没理解怎么找左右比当前小的元素,其实只要把当前元素当成栈顶元素,就很好区分了(之前把遍历到的元素当成当前元素了)

        计算面积时,用栈顶元素当成高,左右下标的差值-1当成宽度,来计算

class Solution {
    public int largestRectangleArea(int[] heights) {
        //遇到一个较大的,往前计算?
        //单调栈之前是怎么做的
        //遇到第一个比自己大的,元素,。
        //遇到第一个比自己小的来计算?
        //因为它是计算最大面积,是从最小下标开始看大小的
        //单调栈:遇到第一个比当前元素大的然后弹出?逐个计算?
        //逐个计算
        //卡哥思路,单调栈,不过是单调递减,当我们遇到左边第一个比它小的元素和右边第一个比它小的元素,计算矩形的面积
        //如何记录下标呢,栈里存下标,然后获取
        //当前元素为栈顶元素,当遇到第一个比栈顶元素小的,开始回收面积
        //遇到的第一个比栈顶元素小的,为右边第一个比它小的元素,左边第一个比它小的元素为,栈顶第二个元素
        Stack<Integer> stack = new Stack<>();
        //使用一个新数组,左右补0
        //为什么要补0?若为递减的数组,永远找不到第一个比栈顶小的元素,所以要在最后补0
        //前面补0,考虑第一个元素,要找到左边比它小的,所以需要补个0
        int[] newHeights = new int[heights.length+2];
        newHeights[0] = 0;
        newHeights[heights.length+1]=0;
        for(int i=0;i<heights.length;i++){
            newHeights[i+1] = heights[i];
        }
        stack.push(0);
        int result = 0;
        for(int i=1;i<newHeights.length;i++){
            //若当前元素比栈顶的要大直接入栈
            if(newHeights[i]>=newHeights[stack.peek()]){
                stack.push(i);
            }else{
                while(!stack.isEmpty()&&newHeights[i]<newHeights[stack.peek()]){
                    //当前元素
                    int item = stack.pop();
                    //找到了左边比它小的和右边比它小的,要怎么计算呢
                    //左边比它小的下标-右边比它小的下标-1
                    if(!stack.isEmpty()){
                        //right 应该为i
                        int right = i;
                        //left 应该为peek
                        int left = stack.peek();
                        result = Math.max((right-left-1)*newHeights[item],result);
                
                    }
                }
                stack.push(i);
            }
        }
        return result;
    }
}

单调栈是一种常用的数据结构,用于解决一类特定的问题,其中最常见的问题是找到数组中每个元素的下一个更大或更小的元素。在Codeforces编程竞赛中,单调栈经常被用于解决一些与数组相关的问题。 下面是单调栈的一般思路: 1. 创建一个空栈。 2. 从左到右遍历数组元素。 3. 对于每个元素,将其与栈顶元素进行比较。 - 如果当前元素小于等于栈顶元素,则将当前元素入栈。 - 如果当前元素大于栈顶元素,则将栈顶元素弹出,并将当前元素入栈。 4. 重复步骤3,直到遍历完所有元素。 这样,最后剩下的栈中元素就是没有下一个更大或更小元素的元素。在使用单调栈求解具体问题时,我们可以根据需要进行一些特定的操作。 例如,如果要找到一个数组中每个元素的下一个更大的元素,可以使用单调递减栈。具体操作如下: 1. 创建一个空栈和一个空结果数组。 2. 从左到右遍历数组元素。 3. 对于每个元素,将其与栈顶元素进行比较。 - 如果当前元素小于等于栈顶元素,则将当前元素入栈。 - 如果当前元素大于栈顶元素,则将栈顶元素弹出,并将其在结果数组中的位置记录为当前元素的下一个更大元素的索引。 4. 将当前元素入栈。 5. 重复步骤3和4,直到遍历完所有元素。 6. 结果数组中没有下一个更大元素的位置,可以设置为-1。 以下是一个使用单调递减栈求解下一个更大元素问题的示例代码: ```cpp #include <iostream> #include <stack> #include <vector> std::vector<int> nextGreaterElement(std::vector<int>& nums) { int n = nums.size(); std::vector<int> result(n, -1); std::stack<int> stack; for (int i = 0; i < n; i++) { while (!stack.empty() && nums[i] > nums[stack.top()]) { result[stack.top()] = i; stack.pop(); } stack.push(i); } return result; } int main() { std::vector<int> nums = {1,3, 2, 4, 5, 1}; std::vector<int> result = nextGreaterElement(nums); for (int i = 0; i < result.size(); i++) { std::cout << "Next greater element for " << nums[i] << ": "; if (result[i] != -1) { std::cout << nums[result[i]]; } else { std::cout << "None"; } std::cout << std::endl; } return 0; } ``` 以上代码将输出: ``` Next greater element for 1: 3 Next greater element for 3: 4 Next greater element for 2: 4 Next greater element for 4: 5 Next greater element for 5: None Next greater element for 1: None ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值