Leetcode::Trapping Rain Water

point

Design

My way

img

Approach 2 (DP)

Approach 3 (Stack)

img

Big O(time)

Code

My way

class Solution {
public:
    typedef long long ll;
    int trap(vector<int>& height) {
        int n = (int)height.size();
        vector<pair<int,int> > h2(n);
        vector<int> top(n, 0);

        for(int i = 0; i < n; i++) h2[i] = {height[i], i};

        sort(h2.rbegin(), h2.rend());

        ll sum = 0, le = -1, ri = -1;
        for (int i = 0; i < n; i++) {
            int id = h2[i].second, h = h2[i].first;
            if (le == -1) le = ri = id, top[id] = h;
            else {
                if (id < le || id > ri) {
                    if (id < le) {
                        for(int j = id; j < le; j++) top[j] = h;
                        le = id;
                    } else {
                        for(int j = ri + 1; j <= id; j++) top[j] = h;
                        ri = id;
                    }
                } else {
                    // do nothing
                }
            }
        }
        for(int i = 0; i < n; i++) {
            sum += (top[i] - height[i]);
        }
        return sum;
    }
};

Approach 2

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        vector<int> leftMax(n, 0), rightMax(n, 0);
        leftMax[0] = height[0], rightMax[n-1] = height[n-1];
        for(int i = 1; i < n; i++) leftMax[i] = max(leftMax[i-1], height[i]);
        for(int i = n-2; i >= 0; i--) rightMax[i] = max(rightMax[i+1], height[i]);

        int ans = 0;
        for(int i = 1; i < n -1 ; i++) {
            ans += max( min(leftMax[i-1], rightMax[i+1]) - height[i], 0);
        }
        return ans;
    }
};

Approach 3

class Solution {
public:
    int trap(vector<int>& height) {
        vector<int> stk;
        int ans = 0, current = 0, n = height.size();
        while(current < n) {
            while(!stk.empty() && height[stk.back()] <= height[current]) {
                int top = stk.back();
                stk.pop_back();
                if (stk.empty()) break;

                int dist = current - stk.back() - 1;
                int h = min(height[current], height[stk.back()]) - height[top];
                ans += dist * h;
            }
            stk.push_back(current++);
        }

        return ans;
    }
};