【164、算法:接雨水】

188 阅读1分钟

题目描述:

给定一个数组,数组的每个元素代表一个高度,假设这个数组是一个直方图,求这个直方图能够接到多少单位的雨水。

示例:

输入:[0,1,0,2,1,0,1,3,2,1,2,1] 输出:6

解释:数组中的数字代表高度,可以看成一个直方图,其中高度为1的位置能接到1单位的雨水,高度为2的位置能接到2单位的雨水,高度为3的位置能接到3单位的雨水,因此总共能接到6单位的雨水。

思路:

这道题可以通过暴力解法、动态规划、单调栈等多种方法解决,这里介绍使用双指针的方法。

  • 定义两个指针left和right,初始值分别为数组的第一个和最后一个元素的下标。
  • 定义两个变量left_max和right_max,分别表示左侧最大值和右侧最大值。
  • 如果height[left] < height[right],说明left处能够接到的雨水取决于left_max的值,因此更新left处的雨水量,并将left指针右移一位,更新left_max的值。
  • 如果height[left] >= height[right],说明right处能够接到的雨水取决于right_max的值,因此更新right处的雨水量,并将right指针左移一位,更新right_max的值。
  • 循环以上操作,直到left和right指针重合,计算出总的雨水量。

代码实现:

Java 代码实现如下:

public int trap(int[] height) {
    if (height == null || height.length == 0) {
        return 0;
    }
    int left = 0, right = height.length - 1;
    int left_max = 0, right_max = 0;
    int ans = 0;
    while (left < right) {
        if (height[left] < height[right]) {
            left_max = Math.max(left_max, height[left]);
            ans += left_max - height[left];
            left++;
        } else {
            right_max = Math.max(right_max, height[right]);
            ans += right_max - height[right];
            right--;
        }
    }
    return ans;
}

时间复杂度:O(n) 空间复杂度:O(1)