题目描述
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。
在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
示例
示例2
输入:height = [1,1]
输出:1
示例3
输入:height = [4,3,2,1,4]
输出:16
暴力解法
思路:
双层for循环,找到左右边界值
计算出所有两个点组合所成的面积,求出最大值
时间复杂度 O(n2)
代码
class Solution {
public int maxArea(int[] height) {
int len = height.length;
if (len < 3) {
return height[0] > height[1] ? height[1] : height[0];
}
int max = 0;
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
int temp = (j - i) * (height[i] > height[j] ? height[j] : height[i]);
max = Math.max(max, temp);
}
}
return max;
}
}
双指针
思路
由于可容纳水的高度由两板中的 短板 决定,因此可得如下面积公式
S(i,j)=min(h[i],h[j])×(j−i)
若向内移动短板 ,水槽的短板 min(h[i], h[j])min(h[i],h[j]) 可能变大,因此下个水槽的面积 可能增大 。
若向内移动长板 ,水槽的短板 min(h[i], h[j])min(h[i],h[j]) 不变或变小,因此下个水槽的面积 只会变小 。
因此,初始化双指针指定水槽左右两端,循环每轮将短板向内移动一格,并更新面积最大值,直到两指针相遇时跳出;即可获得最大面积。
代码
class Solution {
public int maxArea(int[] height) {
int i = 0, j = height.length - 1, res = 0;
while (i < j) {
res = height[i] > height[j] ? Math.max(res, (j - i) * height[j--]) : Math.max(res, (j - i) * height[i++]);
}
return res;
}
}