標籤:leetcode
Trapping Rain Water
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!
思路:此題咋一看簡單,但是細細思考,越想越複雜,感覺無從下手,無奈想了一天沒搞定,只能求助網上資料,終于思路如下:(網友很強大)
(參考網址:http://www.xuebuyuan.com/1586534.html)
最後黑體字的Thanks Marcos的意思是讓我們放大我們的想象力,因為很容易誤導我們的。如果只有的情況的話,我們可以很好用貪進法解決,但是,用貪進法是會出錯的,因為如果我們計算當前最低點,然後往兩邊擴充找到兩邊遞增的最高點,那麼這個最高點很可能是局部最高點,答案就會出錯。
有兩個解題思路:
1 兩邊往中間搜尋
2 由左往右搜尋,跳躍式計算
如下面的分析圖,會比較直觀:
藍色代表水,可以看見很多局部最高點都被水淹了。
這裡計算面積不用一般幾何書的方法,這裡是兩邊往中間遍曆,記錄當前第二高點secHight,然後利用這個第二高點減去當前曆經的柱子,剩下就裝水容量了。
為什麼是第二高點?因為兩邊比較,最高的點不用動,只移動第二高點。
第一個思路,按照的思想就能寫出非常簡潔的程式了,時間複雜度為O(n):
本人照著上面的思路寫的代碼如下:
public class Solution { public int trap(int[] height) { Stack<Integer> st = new Stack<Integer>(); if(height.length == 0) return 0; int i = 0; int j = height.length - 1; int ans = 0;//返回的答案 int secHight = 0;//第二個高度(最高的那個不動) while(i < j){ if(height[i] < height[j]){ secHight = Math.max(secHight,height[i]); //因為長度為1,高度也就是面積值,如果height[i]==secHight,則新增面積為0 ans += secHight - height[i]; i++; }else{ secHight = Math.max(secHight,height[j]); //因為長度為1,高度也就是面積值,如果height[i]==secHight,則新增面積為0 ans += secHight - height[j]; j--; } } return ans; }}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
leetCode 42.Trapping Rain Water(凹槽的雨水) 解題思路和方法