42. Trapping Rain Water 计算储水量

给定一个数组, 表示高度,计算存水量。
例子:
Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6

方法1:动态规划

int trap(vector& height) {
    if (height.empty()) { return 0; }
    
	int n = height.size();
	int left_max[n], right_max[n];
	
	left_max[0] = height[0];
	right_max[n - 1] = height[n - 1];
	
        for (int i = 1; i < n; ++i) {
	    left_max[i] = max(left_max[i - 1], height[i]);
	}

	for (int i = n - 2; i >= 0; --i) {
	    right_max[i] = max(right_max[i + 1], height[i]);
	}
	
	int res = 0;
	for (int i = 1; i < n - 1; ++i) {
            res += min(left_max[i], right_max[i]) - height[i];
	}
	return res;
}

方法2:使用栈

    int trap(vector& height) {
        int waiter = 0;
        stack s; // save idx

        for(int i = 0; i < height.size(); ++i) {
            while(!s.empty() && height[s.top()] < height[i]) {
                // 凹形计算waiter, (height[s.top()], height[mid], height[i])组成凹形
                int mid = s.top();
                s.pop();

                if(!s.empty()) {
                    waiter += (min(height[s.top()], height[i]) - height[mid]) * (i - s.top() - 1);
                }
            }
                
            s.push(i);
        }
        
        return waiter;
    }

方法3:双指针

int trap(vector& height)
{
    int left = 0, right = height.size() - 1;
    int ans = 0;
    int left_max = 0, right_max = 0;
    while (left < right) {
        if (height[left] < height[right]) {
            height[left] >= left_max ? (left_max = height[left]) : ans += (left_max - height[left]);
            ++left;
        }
        else {
            height[right] >= right_max ? (right_max = height[right]) : ans += (right_max - height[right]);
            --right;
        }
    }
    return ans;
}
	

 

你可能感兴趣的:(leetcode)