一、题目
给你 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
二、解题思路
其实,容器的底也就是两个数的下标之差,容器的高就是两个数中相对较小的那个数,采用双重循环的方法,将每一种情况全部列出进行对比,最后返回最大值即可。
三、代码如下:
public int maxArea(int[] height) { if(height.length < 2){ return 0; } int max = 0; for(int i = 0;i < height.length - 1;i++){ for(int j = i + 1;j < height.length;j++){ // 获取面积 int result = (j - i)*(height[i] > height[j]?height[j]:height[i]); if(max < result){ max = result; } } } return max; }
就是这效率:
四、补充
思路调整:
上一种方法结果正确,但是效率较低,现在调整思路,采用双指针算法,左右分别采用一个指针,当进行一次计算之后,比较两个数,把最指向较小数的指针向中间移动,原因是,两下标之和减小了,如果想要让乘机更大,就要将容器的高变大,经过循环直到两个指针相遇,结束循环
代码如下:
public int maxArea(int[] height) { if(height.length < 2){ return 0; } int max = 0; // 采用双指针 int left = 0; int right = height.length - 1; while(right > left){ int result = (right - left)*(height[left] > height[right]?height[right]:height[left]); if(result > max){ max = result; } if(height[left] > height[right]){ right--; }else{ left++; } } return max; }
这效率: