11.盛水最多的容器Leetcode
题目描述
给定 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
思路及解答
/*
思路:
暴力解法 O(n^2)
容器必须用有两个垂直的线作为容器的壁
两壁之间所能盛的水的量为两壁之间的水平距离乘以两壁较小的那个数
这道题的目的是找到这个最大值
*/
class Solution {
public int maxArea(int[] height) {
int max = 0;//用max来记录最大的盛水量
int cur = 0;//用cur来记录当前的盛水量
for(int i = 0; i < height.length-1; i++){
for(int j = i+1; j < height.length; j++){
cur = (j-i) * Math.min(height[i],height[j]);
if(max <= cur){
max = cur;
}
}
}
return max;
}
}
/*
思路:
双指针法
这里算的面积就是两壁之间的水平距离乘上两壁中较小的那个数
两壁中,较小的那个值移动
这是因为移动较小的那个值,则保留了较大的那个值,万一移动到的下一个值比保留下的较大的那个值大,则就是距离乘以保留下的较大的那个值
如果移动的是两壁中较大的那个值,万一下一个值变小了,二中间没有用过的壁中有壁这个值更大的,则会造成错误
*/
class Solution{
public int maxArea(int[] height){
int max = 0;
int cur = 0;
int l = 0;
int r = height.length-1;
while(l < r){
cur = (r-l) * Math.min(height[l],height[r]);
if(max < cur)
max = cur;
if(height[l] < height[r])
l++;
else
r--;
}
return max;
}
}