【Day63】代码随想录之单调栈part2——下一个更大元素、接雨水

本文详细介绍了LeetCode中的两道题目,503.下一个更大元素II使用了数组拼接和模拟循环数组的方法,而42.接雨水则利用单调栈技巧,包括求左边元素和计算凹槽面积。
摘要由CSDN通过智能技术生成

今天晚上是刷题的第二弹,继续单调栈,而且有最经典的接雨水的问题,开冲,马上既可以结束了。

今日任务:

  • 503.下一个更大元素II
  • 42.接雨水

题目一:503.下一个更大元素II

Leetcode题目:【503.下一个更大元素II】

在这里插入图片描述

这个题目需要讲究的是循环数组,那可以把两个数组拼起来,但是如何拼起来如何操作:

1.1 方法一:采用数组拼接的方式处理循环数组

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        stack<int> st;
        st.push(0);
        vector<int> nums1(nums.begin(), nums.end());
        nums.insert(nums.end(), nums1.begin(), nums1.end());
        vector<int> result(nums.size(), -1);

        for(int i = 1; i<nums.size(); i++){
            if(nums[i] <= nums[st.top()]) st.push(i);
            else{
                while(!st.empty() && nums[i] > nums[st.top()]){
                    result[st.top()] = nums[i];
                    st.pop();
                }
                st.push(i);
            }
        }
        result.resize(nums.size()/2);
        return result;
    }
};

1.2 方法二:原数组直接模拟(通用方法)

只要是成环的问题,其实可以采用取模的方式来模拟成环的遍历
就是按照单调栈的模板,把i替换成i%nums.size();

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
       stack<int> st;
        vector<int> result(nums.size(),-1);
        st.push(0);
        for(int i = 1; i<nums.size() *2; i++){
            if(nums[i % nums.size()] <= nums[st.top()]){
                st.push(i % nums.size());
            }else{
                while(!st.empty() && nums[i % nums.size()] > nums[st.top()]){
                    result[st.top()] = nums[i % nums.size()];
                    st.pop();
                }
                st.push(i % nums.size());
            }
        }
        return result;
    }
};

题目二:42.接雨水

Leetcode题目:【42.接雨水】

在这里插入图片描述
接雨水这道题目是 面试中特别高频的一道题,也是单调栈 应用的题目,大家好好做做。建议是掌握 双指针 和单调栈,因为在面试中 写出单调栈可能 有点难度,但双指针思路更直接一些。在时间紧张的情况有,能写出双指针法也是不错的,然后可以和面试官在慢慢讨论如何优化。
本体主要采用单调栈来解决这个问题。

左右元素与本元素大的:单调递增栈;
左右元素与本元素小的:单调递减栈;

这个题与之前不同的题目,不仅要去求右边,还要求左边大于他的第一个元素,这样才能形成一个凹槽。如何求左边,其实左边的元素已经在栈里面了,底找到了,左边的柱子找到了,右边的柱子找到了,这样就可以把装的水的体积计算出来了。

在这里插入图片描述
其实此题的思路关键就是:
(1)左侧的如何求:左侧的最近的大于本元素的已经是在栈里面了;
(2)面积如何计算:因为左侧的是在栈中,所以需要先弹出元素来
mid = st.top();
st.pop();
h = min(h[st.top()], h[i]) - mid;
w = i - st.top() -1;

其他的基本跟单调栈的模板没有区别。

class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> st;
        st.push(0);
        int sum = 0;
        for(int i = 1; i<height.size(); i++){
            if(height[i] <= height[st.top()]) st.push(i);
            else{
                while(!st.empty() && height[i]>height[st.top()]){
                    int mid = st.top();
                    st.pop();
                    if(!st.empty()){
                        int h = min(height[i], height[st.top()]) - height[mid];
                        int w = i - st.top() - 1;
                        sum += h*w; 
                    }
                }
                st.push(i);
            }
        }
        return sum;
    }
};
  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值