文章目录
- 概要
- 题解
- 解释代码
- 比较左右高度
- 处理右侧
- 为什么双指针法有效
概要
原题链接:接雨水
题解
思路:双指针
核心思想:对于任意位置 i
,能够存储的雨水量取决于位置 i
左侧和右侧的最大高度中的较小值减去 height[i]
。即 min(leftMax, rightMax) - height[i]
。我感觉这个很好理解,理解了这个,这道题就简单了
public class T42 {public static int trap(int[] height) {if (height == null || height.length <= 2) {return 0;}int left = 0, right = height.length - 1;int leftMax = 0, rightMax = 0;int res = 0;while (left < right) {if (height[left] < height[right]) {if (height[left] >= leftMax) {leftMax = height[left];} else {res += leftMax - height[left];}left++;} else {if (height[right] >= rightMax) {rightMax = height[right];} else {res += rightMax - height[right];}right--;}}return res;}public static void main(String[] args) {int[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};System.out.println(trap(height)); }
}
解释代码
left
和right
指针分别初始化为数组的最左和最右端。leftMax
和rightMax
分别记录遍历过程中左侧和右侧的最大高度。res
用于累计存储的雨水量。
比较左右高度
if (height[left] < height[right]) {
- 如果左侧高度小于右侧高度,则处理左侧:
- 更新左侧最大高度:
if (height[left] >= leftMax) {leftMax = height[left]; }
- 如果当前左侧高度大于等于
leftMax
,更新leftMax
。
- 如果当前左侧高度大于等于
- 计算左侧可以存储的雨水:
else {res += leftMax - height[left]; }
- 否则,当前柱子可以存储的雨水量为
leftMax - height[left]
。将其累加到res
。
- 否则,当前柱子可以存储的雨水量为
- 移动左指针:
left++;
- 更新左侧最大高度:
处理右侧
else {
- 如果右侧高度小于等于左侧高度,则处理右侧:
- 更新右侧最大高度:
if (height[right] >= rightMax) {rightMax = height[right]; }
- 如果当前右侧高度大于等于
rightMax
,更新rightMax
。
- 如果当前右侧高度大于等于
- 计算右侧可以存储的雨水:
else {res += rightMax - height[right]; }
- 否则,当前柱子可以存储的雨水量为
rightMax - height[right]
。将其累加到res
。
- 否则,当前柱子可以存储的雨水量为
- 移动右指针:
right--;
- 更新右侧最大高度:
为什么双指针法有效
- 关键思想:
- 对于任意位置
i
,能够存储的雨水量取决于位置i
左侧和右侧的最大高度中的较小值减去height[i]
。即min(leftMax, rightMax) - height[i]
。
- 对于任意位置
- 左右指针:
- 当
height[left] < height[right]
时,右侧的高度至少是height[right]
,这意味着左侧的最大高度决定了当前柱子left
的存储量。 - 同理,当
height[left] >= height[right]
时,左侧的高度至少是height[left]
,这意味着右侧的最大高度决定了当前柱子right
的存储量。
- 当
力扣有一位大佬给出5种方法,确实让人佩服。5种解答
❤觉得有用的可以留个关注~~❤