Trapping Rain Water

来源:互联网 发布:捷孚凯市场咨询知乎 编辑:程序博客网 时间:2024/06/06 19:24

1.题目

给出 n 个非负整数,代表一张X轴上每个区域宽度为 1 的海拔图, 计算这个海拔图最多能接住多少(面积)雨水。

如上图所示,海拔分别为 [0,1,0,2,1,0,1,3,2,1,2,1], 返回 6

2.算法

算法1:基本思路是维护一个数组,记录一个数左边和右边的最大高度的最小值,如上图所示第3个数是0,左边最大为1,右边最大高度为2取1,又由于第3个数为0则能接1面积雨水。

    public int trapRainWater(int[] heights)     {    if (heights == null || heights.length == 0)    {    return 0;    }    int max = 0;    int res = 0;    int[] container = new int[heights.length];    for (int i = 0; i < heights.length; i++)  //从左向右找最大值    {    container[i] = max;    max = Math.max(max, heights[i]);    }    max = 0;    for (int i = heights.length - 1; i >= 0; i--) //从右往左找最大值    {    container[i] = Math.min(max, container[i]);    max = Math.max(max, heights[i]);    res += container[i] - heights[i] > 0 ? container[i] - heights[i] : 0;//得出成水量    }    return res;    }

算法2:比较两边大小,从小边开始,往里扫描,如果内部比边上还小,可以装水,否则继续比较两边大小,直到两边相等

    public int trapRainWater(int[] heights)     {    if (heights == null || heights.length == 0)    {    return 0;    }    int res = 0;    int l = 0;    int r = heights.length - 1;    while (l < r)    {    int min = Math.min(heights[l], heights[r]);  //找两边小的    if (heights[l] == min) //如果左边小,继续扫描,装水    {    l++;    while (l < r && min > heights[l])    {    res += min - heights[l];    l++;    }    }    else    //如果右边小,继续扫描,装水    {    r--;    while (l < r && min > heights[r])    {    res += min - heights[r];    r--;    }    }    }    return res;    }


0 0