力扣 42. 接雨水 單調棧 dp

https://leetcode-cn.com/problems/trapping-rain-water/
在這裏插入圖片描述

思路一:維護一個單調非升的棧,棧中存儲的是數組的下標,那麼如果height[i]>height[s.top()]height[i]>height[s.top()],此時要判斷一下棧中的元素是不是>=2>=2的,因爲ii作爲右邊界,s.top()s.top()作爲底部,還需要一個左邊界才能計算貢獻。貢獻==高度差*橫座標之差,注意細節問題。

class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> s;
        int ans=0;
        for(int i=0;i<height.size();i++){
            if(s.empty()||height[i]<=height[s.top()])
                s.push(i);
            else{
                int tmp=s.top(),MIN;
                s.pop();
                while(!s.empty()&&height[s.top()]<height[i]){
                    ans+=(height[s.top()]-height[tmp])*(i-s.top()-1);
                    tmp=s.top();
                    s.pop();
                }
                if(!s.empty())
                    ans+=(height[i]-height[tmp])*(i-s.top()-1);
                s.push(i);
            }
        }
        return ans;
    }
};

思路二:dp[i]dp[i]表示在ii左側的最大高度,那麼對於某個位置ii,已知dp[i]dp[i],只要再知道ii右側的最大高度,設爲MAXMAX,如果min(MAX,dp[i])>height[i]min(MAX,dp[i])>height[i],就對答案有貢獻。所以再逆序處理一遍就可以了。

class Solution {
public:
    int trap(vector<int>& height) {
        int MAX=0,ans=0;
        vector<int> dp(height.size(),0);
        for(int i=0;i<height.size();i++){
            dp[i]=MAX;
            MAX=max(MAX,height[i]);
        }
        MAX=0;
        for(int i=height.size()-1;i>=0;i--){
            dp[i]=min(dp[i],MAX);
            MAX=max(MAX,height[i]);
            if(dp[i]>height[i])
                ans+=dp[i]-height[i];
        }
        return ans;
    }
};

思路三:兩個指針,一個從左向右掃,一個從右向左掃,設tmp=min(a[l],a[r])tmp=min(a[l],a[r]),假設a[l]=tmpa[l]=tmp,那麼把tmptmp當作左邊界,a[r]a[r]當作右邊界,移動ll統計貢獻直到在某個位置有a[l]>tmpa[l]>tmp,反之亦然。

class Solution {
public:
    int trap(vector<int>& height) {
        int l=0,r=height.size()-1,ans=0,tmp;
        while(l<r){
            tmp=min(height[l],height[r]);
            if(tmp==height[l]){
                ++l;
                while(l<r&&height[l]<=tmp)
                    ans+=tmp-height[l++];
            }
            else{
                --r;
                while(l<r&&height[r]<=tmp)
                    ans+=tmp-height[r--];
            }
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章