*42. Trapping Rain Water 接雨水

1. 原始題目

給定 n 個非負整數表示每一個寬度爲 1 的柱子的高度圖,計算按此排列的柱子,下雨以後能接多少雨水。數組

 

上面是由數組 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度圖,在這種狀況下,能夠接 6 個單位的雨水(藍色部分表示雨水)。 感謝 Marcos 貢獻此圖。spa

示例:指針

輸入: [0,1,0,2,1,0,1,3,2,1,2,1]
輸出: 6

2. 思路

最簡單的想法:對於每一個元素都要考慮它能接多少雨水:code

第一個元素是0,能接0雨水blog

第二個元素是1,能接0雨水io

第三個元素是0,能接1雨水class

...方法

第六個元素是0,能接2雨水。im

能夠看到,每一個元素能接的雨水量是:當前位置左邊最高的數與右邊最高的數的最小值減去當前位置的數總結

例如第六個元素接水量爲2 = min(2,3)-0=2。

總結:對於每一個位置,都考慮其左邊最高的牆和右邊最高的牆便可。

 

3. 解題

思路圖:

 

 1 class Solution:  2 def trap(self, height):  3 if not height: return 0  4 n = len(height)  5 left,right = [0]*n, [0]*n # 每一個位置都存放其左邊最大值和右邊最大值  6 temp = 0  7 for i in range(n):  8 temp= max(temp,height[i]) # 找每一個元素的左邊最大值(含自身)  9 left[i] = temp 10 temp = 0 11 for i in range(n-1,-1,-1): 12 temp = max(temp,height[i]) # 找每一個元素的右邊最大值(含自身) 13 right[i] = temp 14 res = 0 15 for i in range(n): 16 res+=min(left[i],right[i])-height[i] # 最小的高度值-自身 17 return res

 

方法2. 雙指針法

仍是一個思路:當前位置須要左右兩堵牆的最小值減去當前值。

左右兩端各設定一個指針,初始兩堵牆。若是左端小於右端,則以右端爲牆,當前值等於左牆和右牆的最小值減去當前值。

 1 class Solution:  2 def trap(self, height):  3 if not height: return 0  4  5 left, right = 0 , len(height)-1 # 左右指針  6 area = 0  7 leftwall, rightwall = 0,0 # 左牆和右牆  8 while(left<right):  9 if height[left]<height[right]: # 右邊高,則以右端爲牆 10 if leftwall>height[left]: # 若是左牆也比當前位置高的話 11 area+=min(leftwall,height[right])-height[left] # 面積就是兩牆最低者減去當前位置的高度 12 else: 13 leftwall = height[left] # 不然更新左牆 14 left+=1 15 else: 16 if rightwall>height[right]: 17 area+=min(rightwall,height[left])-height[right] 18 else: 19 rightwall = height[right] 20 right-=1 21 return area
相關文章
相關標籤/搜索