【LeetCode】42. Trapping Rain Water算法及注释

42. Trapping Rain Water

Total Accepted: 72222 Total Submissions: 212130 Difficulty: Hard


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.


The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!




【分析】

     直观来看,左右两侧,能够装水的体积只与较低的一侧相关,某种意义上,我们只需要从一侧进行遍历便可以求出最大装水量。但是,无论我们从哪一侧遍历,另一侧的不确定性都会增加求取装水体积的难度,需要细分求解,因此,我们采用两侧逼近的方法更为妥当,无论中间数据为何种形态,两侧逼近都能较为简洁的求解:

    具体思路:左右下标为left,right,输入数据集名为height,如果height[left]<height[right],即左侧高度低于右侧,那么,装水的量主要由左侧决定,我们移动左侧下标,如果在移动过程中,left下标对用数据大于其右侧数据,则可构成装水容器,计算装水量,并移动下标,直到left下标对应数据小于其右侧数据,我们把left移动至此,此轮循环结束,下一次继续判断height[left]与height[right]的大小,如此,直至left>=right退出,返回结果。

【解法】

class Solution {
public:
    int trap(vector<int>& height)
	{
                int sumOfWater=0;//装水体积
		int left,right;//数组左右下标
		left=0;
		right=height.size()-1;


		while(left<right)//两侧对向移动,循环结束条件
		{
			if(height[left]<height[right])//左侧小于右侧
			{
				int cur=left;//记录当前左侧下标
				while(height[left]>=height[cur]&&cur<right)//若左侧下标对应数据右侧(相邻)数据比它小,则可构成容器
				{
					sumOfWater+=(height[left]-height[cur]);//计算局部装水量
					cur++;
				}
				left=cur;//<span style="font-family: FangSong_GB2312;">将左侧下标移动至从左侧遍历的第一个大于原始值的数的下标处</span>


			}
			else
			{
				int cur=right;
				while(height[right]>=height[cur]&&cur>left)
				{
					sumOfWater+=(height[right]-height[cur]);
					cur--;
				}
				right=cur;
			}
		}
		return sumOfWater;
	}


};





你可能感兴趣的:(LeetCode,C++,算法,注释)