42. 接雨水
1.暴力解法—时间复杂度-N² 空间复杂度-1
- i位置能装的水量,是其左边最高得柱子left_max,右边最高的柱子right_max,取较小的那个min(left_max,right_max) - i的高度,即可求得。
class Solution {
public int trap(int[] height) {
int res = 0;
int len = height.length;
因为数组左右两边的位置不可能存水
for (int i = 1; i < len-1; i++) {
求i左边最高的柱子
int leftMax = maxPartial(height,0,i);
求i右边最高的柱子
int rightMax = maxPartial(height,i,len-1);
求当前位置能存的水
res += Math.max((Math.min(leftMax,rightMax) - height[i]),0);
}
return res;
}
辅助函数实现求取数组i到j位置最大的数
public int maxPartial(int[] height, int i, int j){
int resMax = 0;
for (int k = i; k <= j; k++) {
resMax = Math.max(resMax,height[k]);
}
return resMax;
}
}
2.备忘录优化解法——时间复杂度:N 空间复杂度:N
- 数组left记载每个位置左边最高的柱子;
- 数组right记载每个位置右边最高的柱子;
class Solution {
public int trap(int[] height) {
int res = 0;
int len = height.length;
int[] left = new int[len];
int[] right = new int[len];
1.数组left记载每个位置左边最高的柱子;
int max = height[0];
for (int i = 1; i < len-1; i++) {
max = Math.max(max,height[i]);
left[i] = max;
}
2.数组right记载每个位置右边最高的柱子;
max = height[len-1];
for (int i = len-2; i >= 0; i--) {
max = Math.max(max,height[i]);
right[i] = max;
}
3.计算每个位置的雨水量
for (int i = 1; i < len-1; i++) {
res += Math.max(0,Math.min(left[i],right[i])-height[i]);
}
return res;
}
}
3.双指针优化——时间复杂度:N 空间复杂度:1
left指针,right指针
- l_max: 0~left 左边最高的;
- r_max:right~len-1右边最高的;
class Solution {
public int trap(int[] height) {
int res = 0;
int len = height.length;
int left = 1, right = len - 2;
l_max:0~left 左边最高的
int l_max = height[0];
r_max:right~len-1右边最高的
int r_max = height[len-1];
while (left <= right){
l_max = Math.max(l_max,height[left]);
r_max = Math.max(r_max,height[right]);
if (l_max < r_max){
res += l_max - height[left];
left++;
}else {
res += r_max - height[right];
right--;
}
}
return res;
}
}