一、题目
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。
在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
二、题解
该方法最笨的方法是是,暴力穷举法,也就是把所有两个柱子的情况都试下。
但这个是最耗费时间的。
我们此处的方法,是在暴力穷举法的基础上进行优化,把一些不可能更大的情况,先提前排除掉了。
- 核以思想: 设定两个指针,比较两值大小,谁短移谁。
因为 区域的大小,由短的一方决定,如果移动长的一方,只会方面积更小,不可能更大。
代码如下:
int maxArea(int* height, int heightSize){
// 定义首尾双指针 及 面积大小
int i = 0, j = heightSize-1 , area = 0;
while(i != j){
// 证算当前 i j 位置时, area 的大小
area = area >= (j-i)*height[ height[i]<height[j]?i:j ] ? area : (j-i)*height[ height[i]<height[j]?i:j ];
// 开如移动柱,核心思想就是area的大小由短的柱子决定,谁短移谁
// 因为移动长的柱子,只会让area相等或更小
// 当 左短 右长时,i++ 移动左边
// 当 左长 右短时,j-- 移动右边
// 当 左 右相等时,移动左边右边都行
height[i] < height[j] ? i++ : j--;
}
return area;
}
前面代码 用了太多的三元运算符可能不好理解,我们把三元运算符展开下,就很清晰了
int maxArea(int* height, int heightSize){
// 定义首尾双指针 及 面积大小
int i = 0, j = heightSize-1 , area = 0;
while(i != j){
// 开始移动柱,核心思想就是area的大小由短的柱子决定,谁短移谁
// 当 左短 右长时,i++ 移动左边
if(height[i] < height[j]){
if( area < (j-i)*height[i] )
area = (j-i)*height[i];
i++;
}
// 当 左长 右短时,j-- 移动右边
// 当 左 右相等时,移动左边右边都行
else{
if( area < (j-i)*height[j] )
area = (j-i)*height[j];
j--;
}
}
return area;
}
执行结果如下: