力扣上承水问题有11和42题
一、承最多水的容器
解决思路:
要得到存储最大水量,得到max(长度 * 高度),使用双指针解决这类问题
先判断左指针还是右指针谁大,找最大值,保留最大值,让最小值向中间移动,即可保证高度会相对较高。
设置left左指针和right右指针,设置最大值max,当长度 * 高度大于max时替换,直到遍历完整个数组即可找到最大值max
class Solution {public int maxArea(int[] height) {int left = 0, right = height.length - 1, max = 0;while(left < right ) {//right - left计算长度,height[left++]计算长度,因为左边高度低于右边,让左指针右移一个,如果右边高度低于等于左边,让右指针左移一个。max = height[left] < height[right] ?Math.max(max, (right - left) * height[left++]) :Math.max(max, (right - left) * height[right --]);}return max;}
}
明白解决思路这题会比较简单。
二、接雨水
解决思路:
这题和上面题目类似,都是先找到左右两边最大的高度,找到矮的的那个,需要往中间移动
对比上面问题多两个个需要存储的参数,左边最高值(后面称为左高)和右边最高值(同理)
以左边为例,左高设置为0,判断左指针这个位置的高度是否高于左高,高于将左高值替换成当前左指针的高度,若当前值低于左高,左高-当前高度即为此格收集到的雨水数量,直到左指针大于右指针时结束。右边同理
class Solution {public int trap(int[] height) {//sum代表接雨水的总数//left_max代表左高//right_max则表示右高//left、right代表对应位置int sum = 0;int left_max = 0;int right_max = 0;int left = 1;int right = height.length - 2;while(left <= right){//此判断相当找最大的两边的墙if(height[left - 1] < height[right + 1]){//将左高和left当前高度比较找到最大的left_max = Math.max(left_max, height[left - 1]);//如果左高大于left当前高度,则证明left这一格接到了雨水if(left_max > height[left]){sum += (left_max - height[left]);}left++;}else{//右边同理right_max = Math.max(right_max, height[right + 1]);if (right_max > height[right]) {sum = sum + (right_max - height[right]);}right--;}}return sum;}
}
总结:
接雨水问题解决办法使用双指针可以满足时间复杂度O(n),空间复杂度O(1),且思路容易,后续遇到类似问题以双指针解决即可