LeetCode42.接雨水

思路一:暴力破解

首先我們要找一個最高的柱子,將整個柱子堆劃分爲2部分,即左部分和右部分,我們分別來統計左右部分可以裝的總水量,

以左部分爲例:我們從左部分開頭開始,向右遍歷至中間最高處,

情況1.我們所走的當前位置如果前面有比它高的,那就用

前面最高的高度-當前高度 所得的結果就是這個格子能裝的水的高度

情況2.如果所走的位置比前面最高的還高,那就將最高的記做當前的柱子,再走下一個

有部分:和左部分一樣,只不過從右向左走。遇到的情況還是一樣

/*
	 * 先找出最高的柱子,左邊從左往右,如果該柱子低於前面最高的
	 * 則存水量爲前面最高的減去這個柱子,右邊總右向左走
	 */
	public int trap(int[] height) {
		int begin=0,end=height.length-1;
		int max=0,maxval=0;
		//找到最大值和最大值得下標
		for(int i=0;i<height.length;i++) {
			if(height[i]>maxval) {
				max=i;maxval=height[i];
			}
		}
		int sum=0;
		int flag=0;//前面最高的柱子
		//從左往右找
		for(int i=0;i<max;i++) {
			if(height[i]<flag) {//如果這個柱子小於前面最高的
				sum=sum+(flag-height[i]);
			}
			if(height[i]>=flag)//如果大於等於最高的
				flag=height[i];
		}
		flag=0;
		for(int i=height.length-1;i>max;i--) {
			if(height[i]<flag)//如果這個柱子小於前面最高的
				sum=sum+(flag-height[i]);
			if(height[i]>=flag)//如果大於等於最高的
				flag=height[i];
		}
		return sum;
    }

 

思路二:使用棧

參考:https://www.jianshu.com/p/024d2e3c13e8

類似於括號匹配問題,先找上升趨勢,將其入棧,直到找到下降的,那麼這個下降的柱和上升的柱之間一定存在一個坑,我們就要計算這個坑,然後進一步擴大,計算中間的坑,最後將所有的坑加起來,就是所有的總和。

具體的講解在上面的博客中講了。

下面是具體的代碼

//利用堆棧的方法
	public int trap2(int[] height) {
		//用來存儲height的下標
		Stack<Integer> stack=new Stack<>();
		int sum=0;
		//遍歷數組
		for(int i=0;i<height.length;i++) {
			//如果數組爲空或者數組是遞減順序
			if(stack.isEmpty()||height[i]<height[stack.peek()]) {
				stack.push(i);//此處記錄的是數組的下標
			}else{//當數組不爲遞減順序時,就需要彈棧了
				while(!stack.isEmpty()&&height[i]>height[stack.peek()]) {
					int pre=stack.pop();//彈出棧頂元素
					if(!stack.isEmpty()) {//因爲此處要使用棧前面的元素
						sum+=(min(height[i],height[stack.peek()])-height[pre])*(i-stack.peek()-1);
					}
				}
				stack.push(i);
			}
		}
		return sum;
	}
	private int min(int a,int b) {
		return a<b?a:b;
	}

 

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