题目描述
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
- 设两个点的坐标分别为i和j,高度为ai何aj,那么最大的容器为 m a x A r e a = m i n ( a i , a j ) ∗ ∣ i − j ∣ , \ maxArea = min(ai,aj)*|i-j|, maxArea=min(ai,aj)∗∣i−j∣,
- 有两个变量在变化,一个是i和j 的距离,另一个是ai和aj之间的最小高度
- 主要思路: 控制其中一个变量(距离),遍历另一个变量(高度)
- 初始化i=0,j=length-1 即控制距离最大,然后不断的缩小这个距离,记录最大的面积值,缩短这个距离有两种方式,一个是i往右动,一个是j往左动。最开始,我只想到使用递归的做法,左右各算一次最大值来比较。后来看了题解,移动ai aj两个中的最小值即可,因为如果移动ai,aj两个中的最大值的话,min(ai,aj)没有发生变化,maxArea只能是变小
解法
1.一开始的想法-递归求解(超出时间限制)
class Solution {
public int maxArea(int[] height) {
return findMax(height,0,height.length-1);
}
public int findMax(int[] height, int i,int j){
if(i==j)return 0;
//以i j为端点算maxArea
int sum=Math.min(height[i], height[j])*(j-i);
//以i+1 j为端点
int sum1=findMax(height,i+1,j);
//以i j-1为端点
int sum2=findMax(height,i,j-1);
return Math.max(sum,Math.max(sum1,sum2));
}
}
2. 优化解法(移动最小值)
class Solution {
public int maxArea(int[] height) {
return findMax(height,0,height.length-1);
}
//移动较小的值
public int findMax(int[] height, int i,int j){
if(i==j)return 0;
//以i j为端点
int sum=Math.min(height[i], height[j])*(j-i);
//以i+1 j为端点
int sum_sub;
if(height[i]<=height[j]){
sum_sub=findMax(height,i+1,j);
}else{
sum_sub=findMax(height,i,j-1);
}
return Math.max(sum,sum_sub);
}
}