力扣42.接雨水 | 双指针 |
暴力解法
设立两个数组leftmaxrightmax,leftmax存入每个元素的左边界最大值,rightmax存入每个元素的右边界最大值,取左右的最小的边界减当前元素即为当前元素可存雨水量。然后累加一下返回res。
时间复杂度:O(n)
空间复杂度:O(n)
题解代码:
点击查看代码
class Solution {
public int trap(int[] height) {
int[] leftMax = new int[height.length];
int[] rightMax = new int[height.length];
int left = 0;
for(int i = 0 ; i < height.length ; i++){
left = Math.max(left,height[i]);
leftMax[i] = left;
}
int right = 0;
for(int i = height.length-1; i >= 0; i--){
right = Math.max(right,height[i]);
rightMax[i] = right;
}
int res = 0;
for(int i = 0 ; i < height.length ; i++){
res += Math.min(leftMax[i],rightMax[i]) - height[i];
}
return res;
}
}
双指针法
由暴力解法可知,leftmax从左往右逐渐增大,rightmax从右往左逐渐减小,设left指向数组头,right指向数组尾部,比较当前左右指针的数,如果leftmax<=rightmax,则对于当前元素 一定有 左边界小于右边界 取左边界和当前元素高度做比较取最大值再减去当前元素高度 即为当前元素盛水量,然后左指针向右走一。如果left>right,则对于当前元素 一定有 右边界小于左边界 取右边界和当前元素高度做比较取最大值再减去当前元素高度 即为当前元素盛水量,然后右指针向左减一。直到左指针大于右指针退出循环。
时间复杂度:O(n)
空间复杂度:O(1)
代码:
点击查看代码
class Solution {
public int trap(int[] height) {
int left = 0;
int right = height.length -1;
int leftMax = 0;
int rightMax = 0;
int res = 0;
while(left <= right){
if(leftMax <= rightMax){
leftMax = Math.max(leftMax,height[left]);
res += leftMax - height[left];
left++;
}
else{
rightMax = Math.max(rightMax,height[right]);
res += rightMax - height[right];
right--;
}
}
return res;
}
}
浙公网安备 33010602011771号