標籤:app tar == ref math 數組 ash with trap
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!
有Stack和Two Pointers兩種解法。使用雙指標,left和right分別指向數組的頭尾,從兩邊向中間掃描,在當前兩指標的範圍內,先比較兩頭找出較小值,如果較小值是left指向的值,則從左向右掃描,如果較小值是right指向的值,則從右向左掃描,若遇到的值比當較小值小,則將差值存入結果,如遇到的值大,則重新確定新的視窗範圍,迭代直至left和right指標重合。
對於任何一個座標,檢查其左右的最大座標,然後相減就是容積。所以,
1. 從左往右掃描一遍,對於每一個座標,求取左邊最大值。
2. 從右往左掃描一遍,對於每一個座標,求最大右值。
3. 再掃描一遍,求取容積並加和。
2和3可以合并成一個迴圈,公式:H[i] = min(Max(Array[j] ), Max(Array[k])) – Array[i] where j < i and k > i
Follow up:
不求所有容積,而是求容積中的最大值。這樣就類似於Container With Most Water,但是有不同的地方,這題裡面每一個座標本身是占體積的。所以從兩邊往中間掃的時候,根本不知道中間座標共佔用了多少體積。
Java:
public class Solution { public int trapRainWater(int[] heights) { if (heights.length == 0) { return 0; } int[] maxHeights = new int[heights.length + 1]; maxHeights[0] = 0; for (int i = 0; i < heights.length; i++) { maxHeights[i + 1] = Math.max(maxHeights[i], heights[i]); } int max = 0, area = 0; for (int i = heights.length - 1; i >= 0; i--) { area += Math.min(max, maxHeights[i]) > heights[i] ? Math.min(max, maxHeights[i]) - heights[i] : 0; max = Math.max(max, heights[i]); } return area; }}
類似題目:
[LeetCode] 11. Container With Most Water 裝最多水的容器
[LeetCode] 42. Trapping Rain Water 收集雨水