力扣题目
解题思路
java代码
力扣题目:
给定 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
解题思路:
解题思路 1:暴力法(trap 函数)
- 初始化一个变量
ans
用于累加雨水池的面积。 - 遍历数组
height
中的每个元素(除了最边缘的两个元素),因为最边缘的元素不能形成雨水池。 - 对于每个元素,分别在其左边和右边寻找最高点,分别记为
max_left
和max_right
。 - 雨水池的面积等于
min(max_left, max_right) - height[i]
,将其加到ans
中。
解题思路 2:双指针法(trap1 函数)
- 初始化一个变量
ans
用于累加雨水池的面积。 - 使用两个指针
left
和right
分别指向数组的开始和结束。 - 在数组中间移动两个指针,比较
left
和right
指向的元素高度,将较矮的元素指向的雨水倒入ans
。 - 移动较矮的元素对应的指针,重复步骤3,直到
left
和right
相遇。
这种方法的时间复杂度是 O(n),而暴力法的时间复杂度是 O(n^2)。
java代码:
package org.example.mouth7.today713;
public class Leetcode42 {
public static void main(String[] args) {
int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
int[] height1 = {4,2,0,3,2,5};
System.out.println(trap1(height1));
System.out.println(trap1(height));
}
public static int trap(int[] height) {
int ans = 0;
int size = height.length;
for (int i = 1; i < size - 1; i++) {
int max_left = 0, max_right = 0;
for (int j = i; j >= 0; j--) {
max_left = Math.max(max_left, height[j]);
}
for (int j = i; j < size; j++) {
max_right = Math.max(max_right, height[j]);
}
ans += Math.min(max_left, max_right) - height[i];
}
return ans;
}
public static int trap1(int[] height) {
int ans = 0;
int size = height.length;
int left = 0, right = size - 1;
int left_max = 0;
int right_max = 0;
while (left < right){
left_max = Math.max(left_max, height[left]);
right_max = Math.max(right_max, height[right]);
if (height[left] < height[right]){
ans += left_max - height[left];
left++;
}else {
ans += right_max - height[right];
right--;
}
}
return ans;
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项