42. 接雨水:
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
样例 1:
输入:
height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:
6
解释:
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
样例 2:
输入:
height = [4,2,0,3,2,5]
输出:
9
提示:
- n == height.length
- 1 <= n <= 2 * 104
- 0 <= height[i] <= 105
分析:
- 面对这道算法题目,二当家的陷入了沉思。
- 单看一个位置能接多少雨水,其实是看它左面的最高高度,和右面的最高高度,两者取小,再减去当前位置的高度。
- 如果每一个位置都去计算左右两侧的最高高度,时间复杂度就会是O(n2)
,太慢了,不能忍。 - 在过程中存储左边最高高度和右面最高高度,复用才是正道。
- 遍历的顺序怎么选?无论从左到右还是从右到左,另一边的最高高度都不便计算。
- 那就两边一起遍历吧,那个熟悉的感觉,双指针。
题解:
rust
impl Solution {
pub fn trap(height: Vec<i32>) -> i32 {
let mut ans = 0;
let (mut left, mut right) = (0, height.len() - 1);
let (mut left_max, mut right_max) = (0, 0);
while left < right {
left_max = left_max.max(height[left]);
right_max = right_max.max(height[right]);
if height[left] < height[right] {
ans += left_max - height[left];
left += 1;
} else {
ans += right_max - height[right];
right -= 1;
}
}
return ans;
}
}
go
func trap(height []int) (ans int) {
max := func(a, b int) int {
if a > b {
return a
}
return b
}
left, right := 0, len(height)-1
leftMax, rightMax := 0, 0
for left < right {
leftMax = max(leftMax, height[left])
rightMax = max(rightMax, height[right])
if height[left] < height[right] {
ans += leftMax - height[left]
left++
} else {
ans += rightMax - height[right]
right--
}
}
return
}
c++
class Solution {
public:
int trap(vector<int>& height) {
int ans = 0;
int left = 0, right = height.size() - 1;
int leftMax = 0, rightMax = 0;
while (left < right) {
leftMax = max(leftMax, height[left]);
rightMax = max(rightMax, height[right]);
if (height[left] < height[right]) {
ans += leftMax - height[left];
++left;
} else {
ans += rightMax - height[right];
--right;
}
}
return ans;
}
};
c
int trap(int* height, int heightSize){
int ans = 0;
int left = 0, right = heightSize - 1;
int leftMax = 0, rightMax = 0;
while (left < right) {
leftMax = fmax(leftMax, height[left]);
rightMax = fmax(rightMax, height[right]);
if (height[left] < height[right]) {
ans += leftMax - height[left];
++left;
} else {
ans += rightMax - height[right];
--right;
}
}
return ans;
}
python
class Solution:
def trap(self, height: List[int]) -> int:
ans = 0
left, right = 0, len(height) - 1
left_max = right_max = 0
while left < right:
left_max = max(left_max, height[left])
right_max = max(right_max, height[right])
if height[left] < height[right]:
ans += left_max - height[left]
left += 1
else:
ans += right_max - height[right]
right -= 1
return ans
java
class Solution {
public int trap(int[] height) {
int ans = 0;
int left = 0, right = height.length - 1;
int leftMax = 0, rightMax = 0;
while (left < right) {
leftMax = Math.max(leftMax, height[left]);
rightMax = Math.max(rightMax, height[right]);
if (height[left] < height[right]) {
ans += leftMax - height[left];
++left;
} else {
ans += rightMax - height[right];
--right;
}
}
return ans;
}
}
非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~