算法训练营day59_单调栈(3.24提前打)

算法训练营day59_单调栈(3.24提前打)

503.下一个更大元素II

两个数组拼接到一起;(vector用insert插入,不能直接赋值,因为大小规定了,会越界,要是数组的话,提前开够了空间,不会越界)

从后往前走一遍单调栈;

class Solution {
public:
    int stk[10010],top;
    vector nextGreaterElements(vector& nums) {
        memset(stk,0,sizeof stk);
        top=0;

        int n=nums.size();
        vector t(nums.begin(),nums.end());
        nums.insert(nums.end(),t.begin(),t.end());
        vector ans(n,-1);

        for(int i=n*2-1;i>=0;i--){
            while(top&&nums[i]>=stk[top]) top--;
            if(i

42.接雨水

dp预处理

没用单调栈的思路,没想出来;

这道题就是对于每个柱子,找出左边最大的与右边最大的,取小值,再减去当前柱子高度就是当前柱子的贡献值;

需要注意的是,左边与右边都包括自己,这样的话就算找不到比自己大的,也会自己-自己,贡献值为0;

一个小dp预处理出来i左边最大值的数组,i右边最大的数组;然后直接遍历累加贡献值;

class Solution {
public:
    int lh[20010],rh[20010];
    int trap(vector& height) {
        memset(lh,0,sizeof lh);
        memset(rh,0,sizeof rh);
        int n=height.size();
        
        for(int i=1;i<=n;i++){
            lh[i]=max(height[i-1],lh[i-1]);
        }
        for(int i=n;i>=1;i--){
            rh[i]=max(height[i-1],rh[i+1]);
        }

        int ans=0;
        for(int i=0;i

单调栈

凹槽才会存水,如果是连着递减,那么不会存水,遇到了一个大的,往前依次清算;所以用到了单调栈;

维护一个单调递减的单调栈,遇到一个大的,往前看;

当前栈顶是凹的部分,当前栈顶左边右边都比它大,计算(min(左右高度)-当前高度)*(距离),这个计算的就是当前高度上面能存的雨水;

与动归遍历一下子加一列不同,这里一下子加几排;

要注意的是,最后栈里只有一个元素的时候,就不能算了,因为它没有左边的,不是凹槽,存不了水;

class Solution {
public:
    int stk[20010],cnt;
    int trap(vector& height) {
        memset(stk,0,sizeof stk);
        cnt=0;
        
        int ans=0;
        int n=height.size();
        for(int i=0;iheight[stk[cnt]]){
                int cur=stk[cnt];
                cnt--;
                if(!cnt) break;
                int l=stk[cnt];
                int h=min(height[l],height[i])-height[cur];
                int k=(i-l-1);
                ans+=h*k;
            }
            stk[++cnt]=i;
        }
        return ans;
    }
};

你可能感兴趣的:(代码随想录打卡,算法,leetcode,c++)