1、解题思路
- 双指针法:
使用两个指针,一个从左向右移动(left),一个从右向左移动(right)。维护两个变量,left_max和right_max,分别表示从左到右和从右到左遍历时的最大高度。每次移动高度较小的指针,因为较小的高度决定了当前能够接住的雨水量。计算当前柱子的接水量:min(left_max, right_max) - current_height。
- 动态规划法:
预计算每个柱子左边的最大高度和右边的最大高度。对于每个柱子,接水量为min(left_max[i], right_max[i]) - height[i]。这种方法需要额外的空间存储left_max和right_max数组。
- 单调栈法:
使用单调栈来维护一个递减的柱子高度序列。当遇到一个比栈顶高的柱子时,计算栈顶柱子能够接住的雨水量。这种方法需要额外的栈空间。
2、代码实现
C++(双指针法)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* max water
* @param arr int整型vector the array
* @return long长整型
*/
long long maxWater(vector<int>& arr) {
// write code here
if (arr.empty()) {
return 0;
}
int left = 0, right = arr.size() - 1;
int left_max = arr[left], right_max = arr[right];
int water = 0;
while (left < right) {
if (left_max < right_max) {
left++;
left_max = max(left_max, arr[left]);
water += left_max - arr[left];
} else {
right--;
right_max = max(right_max, arr[right]);
water += right_max - arr[right];
}
}
return water;
}
};
Java
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* max water
* @param arr int整型一维数组 the array
* @return long长整型
*/
public long maxWater (int[] arr) {
// write code here
if (arr.length == 0) return 0;
int left = 0, right = arr.length - 1;
int leftMax = arr[left], rightMax = arr[right];
int water = 0;
while (left < right) {
if (leftMax < rightMax) {
left++;
leftMax = Math.max(leftMax, arr[left]);
water += leftMax - arr[left];
} else {
right--;
rightMax = Math.max(rightMax, arr[right]);
water += rightMax - arr[right];
}
}
return water;
}
}
Python
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# max water
# @param arr int整型一维数组 the array
# @return long长整型
#
class Solution:
def maxWater(self , arr: List[int]) -> int:
# write code here
if not arr:
return 0
left, right = 0, len(arr) - 1
left_max, right_max = arr[left], arr[right]
water = 0
while left < right:
if left_max < right_max:
left += 1
left_max = max(left_max, arr[left])
water += left_max - arr[left]
else:
right -= 1
right_max = max(right_max, arr[right])
water += right_max - arr[right]
return water
3、复杂度分析
- 双指针法:
通过移动两个指针,每次处理较小的那个指针,确保当前柱子能够接住的雨水量由较小的最大高度决定。时间复杂度:O(n),空间复杂度:O(1)。
- 动态规划法:
需要额外的O(n)空间存储left_max和right_max数组。时间复杂度:O(n),空间复杂度:O(n)。
- 单调栈法:
使用栈来维护递减的柱子高度,适合处理复杂的高度变化。时间复杂度:O(n),空间复杂度:O(n)。