標籤:
原題地址
不妨手動類比一下,觀察是否有規律可尋。
假設從位置0開始,我們有一個矩形條
向右擴充,我們遇到了第二個矩形條,假設這個矩形條比第一個矮:
我們繼續向右擴充,直到遇到比第一個矩形條高(或者相等)的矩形條:
那麼顯然,藍色的部分就是裝水的部分,把這部分累加到最終的結果中
然後,以新發現的這個矩形條為左邊界,繼續向右擴充...
通過類比我們發現,先固定一個左邊界,然後不斷向右尋找右邊界,哪個是右邊界呢?第一個比左邊界高(或者相等)的矩形條就是右邊界。
這樣做顯然會有個問題,比如下面這種情況,最右邊的矩形條是最後一個矩形條,此時藍色的部分就不會被算進去,因為最右邊的矩形條比紅色箭頭所指的矩形條矮,它不是右邊界。
怎麼辦呢?倒過來(從右向左)用同樣的方式掃一遍就行了。
但是這樣還有一個問題,看下面的情況。當左右邊界(紅色箭頭所指)等高時,這部分裝水的容量一共會被計算兩次(從左向右掃一次,從右向左掃一次)。
解決方案也很簡單,只要規定,從左向右掃的時候左邊界一定小於右邊界,從右向左掃的時候左邊界一定大於等於右邊界即可。
代碼:
1 int trap(int A[], int n) { 2 int sum = 0; 3 int acc = 0; 4 int i = 0; 5 int j = 0; 6 7 // 從左向右掃 8 i = 0; 9 j = 1;10 acc = 0;11 while (i < n && j < n) {12 if (A[j] < A[i])13 acc += A[i] - A[j];14 if (A[j] > A[i]) {15 sum += acc;16 acc = 0;17 i = j;18 }19 j++;20 }21 22 // 從右向左掃23 i = n - 1;24 j = n - 2;25 acc = 0;26 while (i >= 0 && j >= 0) {27 if (A[j] < A[i])28 acc += A[i] - A[j];29 else {30 sum += acc;31 acc = 0;32 i = j;33 }34 j--;35 }36 37 return sum;38 }
Leetcode#42 Trapping Rain Water