Leetcode題目之"Trapping Rain Water"

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">題目來源:https://leetcode.com/problems/trapping-rain-water/</span>

題目描述:

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.

解題思路:題目意思是說給定一個非負數的一維數組,數組中元素的值表示階梯的高度,如上圖中的黑色部分,階梯的寬度都是1,問最多可以存儲多少雨水?

容易想到的是高的階梯之間可以存儲較多的雨水,所以解題的第一步就是找出峯值階梯,即給定的數組中的峯值,同時滿足height[i]>=height[i-1]和height[i]>=height[i+1]的即爲峯值,頭尾兩個階梯只要滿足大於相鄰的一個階梯即可。找出的峯值存於數組posI中。(如下面程序所示)

第二步是找出posI中的兩個最大值,分別存於變量maxPos1和maxPos2中,從而將整個數組分爲三個部分,兩個最大值中間的部分,左邊的部分和右邊的部分。

第三步是找出用於計算雨水量的關鍵階梯,如下面程序所示。

程序代碼:

int trap(vector<int>& height){

	vector<int> posI;
	vector<int> posIICenter;
	vector<int> posIILeft;
	vector<int> posIIRight;
	int waterSum = 0, sum = 0, lowWidth = 0,waterSumLeft=0,waterSumRight=0,waterSumCenter=0;
	int count = 0, maxPos1 = 0,maxPos2=0,maxLeftTemp=0,maxRightTemp=0,lastLeft=0,lastRight=0;
	bool leftFlag = false, rightFlag = false;

	//construct posI
	if (height.size()<2) return 0;

	if (height[0]>height[1]) {
		posI.push_back(0);
	}
	for (int i = 1; i < height.size() - 1; i++){
		if (height[i] >= height[i - 1] && height[i] >= height[i + 1]){
			posI.push_back(i);
		}
	}
	if (height[height.size() - 1]>height[height.size() - 2]) {
		posI.push_back(height.size() - 1);
	}

	//construct posII=posIILegt+posIICenter+posIIRight
	if (posI.size() < 2) return 0;
	for (int i = 1; i < posI.size(); i++){// find max peak
		if (height[posI[i]]>=height[posI[maxPos1]]){
			maxPos1 = i;
		}
	}
	if (maxPos1==0){
		maxPos2 = 1;
		for (int i = 2; i <posI.size();i++){
			if (height[posI[i]]>=height[posI[maxPos2]]){
				maxPos2 = i;
			}
		}
	}
	else{
		for (int i = 1; i < posI.size(); i++){//find second max peak
			if (height[posI[i]] >= height[posI[maxPos2]] && i != maxPos1){
				maxPos2 = i;
			}
		}
	}
	if (maxPos1 > maxPos2){
		int temp = maxPos1;
		maxPos1 = maxPos2;
		maxPos2 = temp;
	}
	posIICenter.push_back(posI[maxPos1]);
	posIICenter.push_back(posI[maxPos2]);

	if (maxPos1 > 0){
		posIILeft.push_back(posI[maxPos1]);
		for (int i = 0; i < maxPos1; i++){
			if (height[posI[i]] >= height[posI[maxLeftTemp]]){
				maxLeftTemp = i;
			}
		}
		posIILeft.push_back(posI[maxLeftTemp]);
		if (maxLeftTemp == 0){
			leftFlag = true;
		}

		while (!leftFlag){
			lastLeft = maxLeftTemp;
			maxLeftTemp = lastLeft-1;
			for (int i = lastLeft-2; i > -1; i--){
				if (height[posI[i]] >= height[posI[maxLeftTemp]]){
					maxLeftTemp = i;
				}
			}
			if (maxLeftTemp == 0){
				leftFlag = true;
			}
			posIILeft.push_back(posI[maxLeftTemp]);
		}
		
	}//maxPos1>0

	if (maxPos2 < posI.size()-1){
		posIIRight.push_back(posI[maxPos2]);
		maxRightTemp = posI.size() - 1;
		for (int i = posI.size() - 2; i>maxPos2; i--){
			if (height[posI[i]] > height[posI[maxRightTemp]]){
				maxRightTemp = i;
			}
		}
		posIIRight.push_back(posI[maxRightTemp]);
		if (maxRightTemp == posI.size() - 1){
			rightFlag = true;
		}
		
		while (!rightFlag){
			lastRight = maxRightTemp;
			maxRightTemp = lastRight + 1;
			for (int i = lastRight+2; i < posI.size(); i++){
				if (height[posI[i]] >= height[posI[maxRightTemp]]){
					maxRightTemp = i;
				}
			}
			posIIRight.push_back(posI[maxRightTemp]);
			if (maxRightTemp == posI.size() - 1){
				rightFlag = true;
			}
		}
	}//maxPos2 < posI.size()-1

	//caculate rainwater
	// waterSum=waterSumLeft+waterSumCenter+waterSumRight
	if (height[posI[maxPos1]] >= height[posI[maxPos2]]){
		for (int i = posI[maxPos1] + 1; i < posI[maxPos2]; i++){
			if (height[i] < height[posI[maxPos2]]){
				sum = sum + height[i];
				lowWidth = lowWidth + 1;
			}
		}
		waterSumCenter = height[posI[maxPos2]] * lowWidth - sum;
	}
	else{
		for (int i = posI[maxPos1] + 1; i < posI[maxPos2]; i++){
			if (height[i] < height[posI[maxPos1]]){
				sum = sum + height[i];
				lowWidth = lowWidth + 1;
			}
		}
		waterSumCenter = height[posI[maxPos1]] * lowWidth - sum;
	}
	sum = 0;
	lowWidth = 0;
	
	if (posIILeft.size() > 1){
		for (int i = 0; i<posIILeft.size() - 1; i++){
			sum = 0;
			lowWidth = 0;
			for (int j = posIILeft[i+1] + 1; j<posIILeft[i]; j++){
				if (height[j] < height[posIILeft[i + 1]]){
					sum = sum + height[j];
					lowWidth = lowWidth + 1;
				}
			}
			waterSumLeft = waterSumLeft + height[posIILeft[i + 1]] * lowWidth - sum;
		}
	}
	sum = 0;
	lowWidth = 0;

	if (posIIRight.size() > 1){
		for (int i = 0; i<posIIRight.size() - 1; i++){
			sum = 0;
			lowWidth = 0;
			for (int j = posIIRight[i] + 1; j < posIIRight[i + 1]; j++){
				if (height[j] < height[posIIRight[i + 1]]){
					sum = sum + height[j];
					lowWidth = lowWidth + 1;
				}
			}
			waterSumRight = waterSumRight + height[posIIRight[i+1]] * lowWidth - sum;
		}
	}

	waterSum = waterSumLeft + waterSumCenter + waterSumRight;
	return waterSum;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章