题目链接
https://leetcode.cn/problems/container-with-most-water/
1、题目要求
给定一个长度为 n 的整数数组 height(就是个数组名字,里面保存几个数字) 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
2、思路分析
解题的详细思路:
可以参考链接中的动图,学习其中的思路
定义两个指针,也就是数组中的两个索引,一个指向数组的最左边,也就是 height[0], 一个指向数组的最右边,也就是 height[length - 1];
循环的步骤:
1、最开始的时候,左指针指向数组的最左边,右指针指向数组的最右边
2、计算左右指针和 x 轴围起来所可以容纳的水,计算公式为:容纳的水 = min(height[ left ], heught[ right ]) * ( right - left ) ;
对于当前左右指针可以计算出来的容量与已有的保存最大的容量进行对比,当前两个指针形成的容量大于已有最大容量,更新即可,否则,保持原状;
当前的左右指针可以计算出来的容量结束,需要修改指针指向的数据,进行下一次的容量的计算;
3、进行循环遍历计算
3、执行代码
class Solution {
public int maxArea(int[] height) {
// 容纳最多的水 = min(height[l], heught[r]) * (r - l)
// 定义双指针,一个指向数组最左边,一个指向数组最右边
int left = 0;
int right = height.length - 1;
int result = 0;
while (left < right) {
// 计算容器中谁的容量
int area = Math.min(height[left], height[right]) * (right - left);
result = Math.max(area, result);
// 存在两种情况,一种是左指针和右指针指向的元素相同,一种是左指针和右指针指向的元素不同
if (height[left] <= height[right]) {
left++;
} else {
right--;
}
}
return result;
}
}
4、问题反思
4.1、左右指针怎么移动?
// 寻找下一个容器的边界,依靠左右两者指针的移动实现
// 寻找下一个容器的边界的思想是:移动左边或者后边的边界,哪儿个指针对应的数值小就移动谁;
// 比如左指针指的数组值小于右指针指的数组值,那么左指针向右边移动
// 比如右指针指的数组值小于左指针指的数组值,那么右指针向左边移动
4.2、时间复杂度以及空间复杂度
时间复杂度:O(n);
空间复杂度:O(1);
5、小结
基于双指针法,计算出来了一个数组中可以容纳的最多的水(只是符合本题目) , 使用双指针法可以有效的降低时间复杂度,此题目可以使用双重循环解决,但是时间复杂度是 O(n^2) ,是比较浪费时间的,不建议使用;