42. 接雨水(Trapping Rain Water)

题目描述:

解题思路:

  这道题主要是区分不同情况。假设从最左边的的柱子开始判断,因为该柱子的左边没有柱子,所以它一定是左边界柱子。那么我们就往右边寻找和这个柱子匹配的右边界柱子。有两种情况:

  第一种情况,当右边有比该柱子高或一样高的柱子时,那么右边界柱子就一定是这根柱子,而中间的所有短柱子都是障碍物,所以我们需要计算左右边界的容量减去中间所有短柱子高度的和,就得到了这块区域最后的容量。之后以右边界柱子为起点,寻找下一个右边界柱子即可。

  第二钟情况,当右边没有高度大于等于该柱子的柱子时,右边界柱子就是所有短柱子中最高的那一个。所以我们需要在遍历的过程中,记录下最高的短柱子的坐标。这种情况下,同样计算左右边界的容量减去中间柱子的高度和,就得到了最后的容量。然后以右边界柱子为起点,寻找下一个右边界柱子。

  需要注意的是,我们可以在遍历过程中就记录中间短柱子的高度和,最后直接减去即可,避免重复遍历。另外左右两端如果有高度为0的柱子可以提前处理掉。

  代码如下:

class Solution
{
public:
    int trap(vector<int>& height)
    {
        if (height.empty())
            return 0;
        auto p = height.end() - 1;
        while (p >= height.begin() && *p == 0)
            --p;
        if (p + 1 == height.begin())
            return 0;
        height.erase(p + 1, height.end());
        int ret = 0;
        int i = 0;
        while (i < height.size() && height[i] == 0)
            ++i;
        while (i < height.size() - 1)
        {
            int j = i + 1, tall = j, sum = 0, tall_sum = 0;
            while (j < height.size())
            {
                if (height[j] >= height[i])
                    break;
                if (height[tall] < height[j])
                {
                    tall = j;
                    tall_sum = sum;
                }
                sum += height[j];
                ++j;
            }

            if (j == height.size())
            {
                ret += (tall - i - 1) * height[tall] - tall_sum;
                i = tall;
            }
            else
            {
                ret += (j - i - 1) * height[i] - sum;
                i = j;
            }
        }
        return ret;
    }
};

 

posted @ 2020-06-26 20:38  简讯  阅读(176)  评论(0编辑  收藏  举报