难得遇到一道困难的打卡题,就在这里写一下过程吧(虽然并不是很困难。。。)

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

p1

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

结果

p2

首先想到的应该就是暴力法。不过暴力法没有多少分析的价值,所以略过不谈。

个人认为,无论何时,暴力法都应该作为一个最后的保命手段来用比较好的。如果条件允许,还是去追求一些高效率的解法,这样每日的打卡才有意义。

这里用分解子问题的思路,将这个问题进行拆分。

两根柱子之间可以存放多少水?

  1. 由范围内第二高的柱子决定
  2. 去掉范围内的柱子占有的空间

如此一来,子问题的条件就集齐了。同时,这个问题具有迭代性质。

思路部分到这里就结束了。

以下为代码,这里首次尝试了全迭代器的写法,感觉还不错,有复健的感觉了。

int trap(vector<int>& height) {
        int res=0;
        if(size(height) == 1 or size(height) == 0) return 0;
        auto maxPosition = max_element(height.begin(), height.end());
        auto left = maxPosition;
        auto right = max_element(maxPosition+1,height.end());
        while(left != height.begin()){
            left = max_element(height.begin(),maxPosition);
            res+= (distance(left,maxPosition)-1)**left - accumulate(left+1,maxPosition,0);
            maxPosition = left;
        }
        maxPosition = max_element(height.begin(), height.end());
        while(right != height.end()){
            res+= (distance(maxPosition,right)-1)**right - accumulate(maxPosition+1,right,0);
            maxPosition = right;
            right = max_element(maxPosition+1,height.end());
        }
        return res;
    }