LeetCode11. 盛最多水的容器
题目描述
/**
* 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。
* 在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。
* 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
*
*/
思路分析
- 使用双指针法,定义left和right指针分别指向数组的左右两端的下标,
- leftHeight和rightHeight为左右指针对应的数组元素大小
- 计算左右两端高度能形成的面积并记录(注意以最低高度为准计算,不然水会漏)
- 比较左右指针的大小,向左或者向右移动较小的指针,使指针指向下一个
- 每次移动,都计算形成的面积,并和之前计算的面积比较,记录最大的面积
- 移动到两指针重叠的时候,说明所有的高度都已经使用过
- 而最大的面积也已经记录,返回即可
- 详细思路见源码
源码及详解
/**
* @param height 数组中存储了不同高度的数字
* @return 返回容器中能存储最多水的面积
*/
//思路分析:
//1. 使用双指针法,定义left和right指针分别指向数组的左右两端的下标
// leftHeight和rightHeight为左右指针对应的数组元素大小
//2. 计算左右两端高度能形成的面积并记录(注意以最低高度为准计算,不然水会漏)
//3. 比较左右指针的大小,向左或者向右移动较小的指针,使指针指向下一个
//4. 每次移动,都计算形成的面积,并和之前计算的面积比较,记录最大的面积
//5. 移动到两指针重叠的时候,说明所有的高度都已经使用过
//6. 而最大的面积也已经记录,返回即可
public int maxArea(int[] height) {
//数据校验
if (height == null || height.length < 2) {
return 0;
}
//定义左右两个指针
//说明:left和right为左右指针下标
int left = 0;
int right = height.length - 1;
//leftHeight和rightHeight为左右指针对应的数组元素大小
int leftHeight = height[left];
int rightHeight = height[right];
//定义变量保存最大面积
int maxSize = 0;
//当指针指向最左或者最右使时的面积,即最初始的面积
maxSize = Math.min(leftHeight, rightHeight) * (right - left);
//循环比较
while (true) {
//记录最初始的面积后,根据左右两侧数组元素的大小移动相应的指针
//如果左侧元素大于右侧元素,移动右侧指针
if (leftHeight > rightHeight){
right--;
}else {
//如果左侧元素小于右侧元素,移动左侧指针
left++;
}
//如果左右指针在移动的过程中重叠,则结束
if (left == right) {
break;
}
//指针移动后重置左右两侧数组元素的大小
leftHeight = height[left];
rightHeight = height[right];
//定义临时变量计算左右两指针形成的最大面积
int temp = Math.min(leftHeight, rightHeight) * (right - left);
//如果新计算的面积大于以前计算的面积,则重置
//保证了maxSize存储的是最大的面积
if (temp > maxSize){
maxSize = temp;
}
}
//返回
return maxSize;
}