题目来源:https://leetcode.com/problems/trapping-rain-water/
问题描述
42. Trapping Rain Water
Hard
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.
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!
Example:
Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
------------------------------------------------------------
题意
给定正整数数组height, 求如此形状的容器可以容纳的液体体积
------------------------------------------------------------
思路
这个题难在对问题的建模,如果能想到计算每个位置对容积的贡献,后面就很容易了。
针对每个位置计算,一个位置上可以容纳的体积 = min(左侧的最高值,右侧的最高值) – 该位置的高度(1)。因此先用动态规划求出数组lmax, rmax(lmax[i] = max(height[0:i]), rmax[i] = max(rmax[i:n])),复杂度O(n),再遍历除去头和尾的所有位置,按公式(1)计算每个位置对容积的贡献。其中要注意的是尽管公式(1)的min里面写的“左侧的最高值”和“右侧的最高值”,但实际上代码里要写lmax[i]和rmax[i],而不能写lmax[i-1]和rmax[i+1],因为可能出现height[i] > min(左侧的最高值,右侧的最高值)的情况,此时该位置对容积的贡献应当为0而不应当为负。
------------------------------------------------------------
代码
class Solution {
public int trap(int[] height) {
int area = 0, n = height.length, i = 0;
if (n == 0)
{
return 0;
}
int[] lmax = new int[n], rmax = new int[n]; // lmax: max value in height[0:i], rmax: max value in height[i:n]
lmax[0] = height[0];
for (i=1; i<n; i++)
{
lmax[i] = Math.max(lmax[i-1], height[i]);
}
rmax[n-1] = height[n-1];
for (i=n-2; i>=0; i--)
{
rmax[i] = Math.max(rmax[i+1], height[i]);
}
for (i=1; i<n-1; i++)
{
area += Math.min(lmax[i], rmax[i]) - height[i];
}
return area;
}
}