LeetCode42. 接雨水
阿新 • • 發佈:2018-12-09
題目
給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。
上面是由陣列 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度圖,在這種情況下,可以接 6 個單位的雨水(藍色部分表示雨水)。 感謝 Marcos 貢獻此圖。
示例:
輸入: [0,1,0,2,1,0,1,3,2,1,2,1] 輸出: 6
分析
1.自己一開始的想法:把上圖分為一層一層,每一層的高度為1,用棧分別計算每層的凹進去格子個數,加在一起,哈哈哈哈哈,資料量小還可以用,資料量一大,就超時了,時間複雜度O(n^2)。
2.還是看了解題報告,只要遍歷三次,就可以得出結果,哇塞好神奇。
其實這個題只要能知道第x個柱子的 左邊最高柱子 和 右邊最高柱子 中比較矮的一個,然後用較矮柱子的高度減去當前第x個柱子的高度,就是當前x柱子可以接住的雨水量。
說的有點兒繞,寫成表示式就是: x柱子接住雨水量 = min( left_max, right_max) - height[x]
程式碼
class Solution { public int trap(int[] height) { int len = height.length; if (len == 0) return 0; int[] left_max = new int[len]; int[] right_max = new int[len]; int max = height[0]; for (int i = 0; i < len; i++) { if (max > height[i]){ left_max[i] = max; }else{ left_max[i] = height[i]; max = height[i]; } } max = height[len-1]; for (int i = len-2; i >= 0; i--) { if (max > height[i]){ right_max[i] = max; }else{ right_max[i] = height[i]; max = height[i]; } } int sum = 0; for (int i = 1; i < len-1; i++) { sum += Math.min(left_max[i],right_max[i]) - height[i]; } return sum; } }