0042. Trapping Rain Water - kumaeki/LeetCode GitHub Wiki
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Example 1:
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) 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.
Example 2:
Input: height = [4,2,0,3,2,5]
Output: 9
Constraints:
n == height.length
0 <= n <= 3 * 10^4
0 <= height[i] <= 10^5
储藏的水由左右两侧中比较矮的那边决定.
class Solution {
public int trap(int[] height) {
if(height == null || height.length <3)
return 0;
int res = 0, len = height.length;
// 从左到右, 到当前位置为止最高的高度
int[] left = new int[len];
left[0] = height[0];
for (int i = 1; i < len; i++)
left[i] = Math.max(left[i - 1], height[i]);
// 从右到左, 到当前位置为止最高的高度
int[] right = new int[len];
right[len - 1] = height[len - 1];
for (int i = len - 2; i >= 0; i--)
right[i] = Math.max(right[i + 1], height[i]);
// 储存的水由左右侧较矮的那边决定
for (int i = 0; i < len; i++)
res += (Math.min(left[i], right[i]) - height[i]);
return res;
}
}
解法1的优化, 我们定义左右两个游标, 从两侧往中间走.
class Solution {
public int trap(int[] height) {
int res = 0, left = 0, right = height.length - 1;
int maxL = 0, maxR = 0;
while (left < right) {
int hl = height[left], hr = height[right];
if (hl <= hr) {
if (hl >= maxL)
maxL = hl;
else
res += (maxL - hl);
left++;
} else {
if (hr >= maxR)
maxR = hr;
else
res += (maxR - hr);
right--;
}
}
return res;
}
}
class Solution {
public int trap(int[] height) {
int res = 0, len = height.length;
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < len; i++) {
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int low = stack.pop();
if (!stack.isEmpty()) {
int w = i - stack.peek() - 1;
res += (Math.min(height[i], height[stack.peek()]) - height[low]) * w;
}
}
stack.push(i);
}
return res;
}
}