leetcode 42 接雨水

原本想着和LeetCode84柱状图中最大矩形的题是类似的,尝试着用单调栈的方式解,但好像不对。
 
84那道题用单调栈能解是因为,每次拿出一个坐标下的柱状图长度的时候,我都能立刻知道这个柱状图能不能和右面的柱状图拼接在一起。而这道题还需要左右的矩形协助才能知道能接多少雨水。
 
换一种说法,用单调栈的时候只能看到池子一边的高度,无法同时看到池子两边的高度,所以无法判断该向其中加多少水。

 
因为两端高中间低才能放的下雨水,所以假设中间一定有一个高度是最高的。那么从两端开始向中间遍历,就是一步一步从低走到高的过程。
 
用mleft来维护一个左侧池子的左端,mright维护右侧池子的右端,用两个指针i,j分别表示左侧池子的右端和右侧池子的左端。那么我每走一步,只要当前高度比池子边缘低,我就可以将高度差中注上水(这里不考虑池子的另一端是因为我们在最开始做了假设,中间一定有一个最高的高度。)每次移动的时候移动的是i和j中高度较小的那一个,这样就能保证,最后访问到的高度一定是中间最高的(之一)。
 

class Solution
{
public:
    int trap(vector &height)
    {
        int len = height.size();
        if (len == 0)
            return 0;

        int left = 0, right = len - 1, mleft = height[0], mright = height[len - 1];
        int sum = 0;
        while (left < right)
        {
            if (height[left] < height[right])
            {
                if (height[left] > mleft)
                    mleft = height[left];
                else
                    sum += mleft - height[left];
                left++;
            }
            else
            {
                if (height[right] > mright)
                    mright = height[right];
                else
                    sum += mright - height[right];
                right--;
            }
        }

        return sum;
    }
};

你可能感兴趣的:(LintCode)