代码随想录训练营第五十九天|503.下一个更大元素||、42.接雨水

503.下一个更大元素||

链接:LeetCode503下一个更大元素||
既然可以循环的利用数组中的元素寻找下一个更大的元素,故将nums数组扩展为原来的二倍,后一半的元素重复前一半的元素。剩下的和”下一个更大的温度“一样

class Solution {
public:
    typedef pair<int,int> pa;
    vector<int> nextGreaterElements(vector<int>& nums) {
        int len = nums.size();
        for(int i=0;i<len;++i) nums.push_back(nums[i]);
        stack<pa> st;
        st.push(pa{nums[0],0});
        vector<int> ans(len,-1);
        for(int i=1;i<nums.size();++i){
            while(!st.empty()&&nums[i]>st.top().first){
                if(st.top().second<len)ans[st.top().second] = nums[i];
                st.pop();
            }
            st.push(pa{nums[i],i});
        }
        return ans;
    }
};

42.接雨水

链接:LeetCode42.接雨水

暴力解法(双指针)

按照列计算
在这里插入图片描述
按照列计算,宽度是1,此时把每一列的高度求出来就可以了。
每一列雨水的高度取决于该列左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度。

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        for(int i=0;i<height.size();++i){
            int lheight = height[i];//左边柱子的最高高度
            int rheight = height[i];//右边柱子的最高高度
            if(i==0 || i==height.size()-1) continue;//第一根柱子和最后一根柱子不接雨水
            for(int j=i+1;j<height.size();++j) if(height[j]>rheight) rheight=height[j];
            for(int j=i-1;j>=0;--j) if(height[j]>lheight) lheight = height[j];
            int h = (lheight<rheight?lheight:rheight) - height[i];
            if(h>0) ans += h;
        }
        return ans;
    }
};

双指针优化

把每一个位置的左边最高高度记录在一个数组上maxLeft ,右边最高高度记录在一个数组上maxright.这样就避免了重复计算

class Solution {
public:
    int trap(vector<int>& height) {
        vector<int> maxlheight(height.size(),0);
        vector<int> maxrheight(height.size(),0);
        maxlheight[0] = height[0];
        for(int i=1;i<height.size();++i){
            maxlheight[i] = max(height[i],maxlheight[i-1]);
        }
        maxrheight[height.size()-1] = height[height.size()-1];
        for(int i=height.size()-2;i>=0;--i){
            maxrheight[i]=max(maxrheight[i+1],height[i]);
        }
        int ans = 0;
        for(int i=0;i<height.size();++i){
            if(i==0 || i==height.size()-1) continue;//第一根柱子和最后一根柱子不接雨水
            int h = min(maxlheight[i],maxrheight[i]) - height[i];
            if(h>0) ans += h;
        }
        return ans;
    }
};

单调栈

寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时就要使用单调栈。

class Solution {
public:
    typedef pair<int,int>pa;
    int trap(vector<int>& height) {
        if(height.size()<3) return 0;
        int ans=0;
        stack<pa> st;
        for(int i=0;i<height.size();++i){
            while(!st.empty()&&height[i]>st.top().first){
                if(st.size()>=2){
                    int mid = st.top().first;st.pop();
                    // while(!st.empty()&&st.top().first<=mid) st.pop();
                    // if(st.empty()) break;
                    int le = st.top().first;
                    int width = i-st.top().second-1;
                    int len = (height[i]<le?height[i]:le) - mid;
                    ans += width*len;
                    //cout<<width<<"  "<<len<<"  "<<ans<<"  ";
                }else st.pop();
            }
            st.push(pa{height[i],i});
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值