[Leetcode 42] Trapping Rain Water

来源:互联网 发布:淘宝开店需要的csv 编辑:程序博客网 时间:2024/05/16 14:27
  • Question
    Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

图示

  • 思路
    对第一个不为0 的柱子,记录下它的位置t1, 遍历它之后的柱子(用 h 保存它之后的柱子的最高高度,记录相应位置t2), 遇到比t1柱子高的柱子或者遍历完数组停止。 h=min(t1,t2), 再从t1遍历到t2, 这样这可以找到t1与t2围成的最大容积。
    重复这一过程,可以计算出所有的容积。该方法时间复杂度O(n2)

  • 代码如下:

class Solution {public:    int trap(vector<int>& height) {        int ret=0;        for(auto it=height.begin(); it!=height.end(); ){            if(*it==0) ++it;               else{                //找到第一个不为0的柱子t1                decltype(it) it2=it, end_it;                int temp=*it;                  int h=0;                ++it2;                //遍历t1之后的柱子,找到其后第一个高度大于t1的柱子,若没有,则找到后面最高的柱子t2                while(it2 !=height.end()){                  if(*it2>=h){                      h=*it2;                      end_it=it2;                  }                  if(*it2>temp) break;                  ++it2;                }                 if(h==0 && it2==height.end()) break;                h=min(h, temp);                while(it!=end_it){                    if(*it<h) ret+=(h-*it);                    ++it;                }            }        }        return ret;    }};
  • 下面是我在讨论区发现一个非常棒的解法,只需要维护目前的最高水位, 不断抛弃最左或者最右的低的柱子。 该方法只需要遍历一遍数组,时间复杂度O(n).
class Solution {public:    int trap(vector<int>& height) {        if(height.empty()) return 0;        auto left=height.begin(),right=height.end()-1;        int level=0, water=0, lower=0;        while(left<right){            //找到较低的柱子            lower=*left<*right? *left++:*right--;            if(level<lower) level=lower;  //维护最高水位            else                water+=level-lower;  //可以容纳的水量        }        return water;    }};
原创粉丝点击