一. 题目描述
给定 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
二. 思路
这里直接套用LeetCode官方的思路原话。
我们在由线段长度构成的数组中使用两个指针,一个放在开始,一个置于末尾。 此外,我们会使用变量 maxarea 来持续存储到目前为止所获得的最大面积。 在每一步中,我们会找出指针所指向的两条线段形成的区域,更新 maxarea,并将指向较短线段的指针向较长线段那端移动一步。
这里增加说明为什么要往较长线段那段移动,而不是向较短线段那方移动。
这是因为,如果向着较短线段那方移动,那么容器的高不会高于短线段的高,而容器的长也不会比现在的长度长,那么,这种移动方式,就会导致容器的容量只有更小,没有更大的可能,所以,要往较长线段方向移动。
就我的感觉来说,这里还是用到了一点贪心的思想,当前情况下,只有向较长线段方向移动才有可能得到更大的容量,所以当前向较长线段方向移动,然后,每一步都是这样进行的,而每一步的策略都是正确的,最后出来的结果就是正确的。
三. 代码
class Solution {
public int maxArea(int[] height) {
int index_head = 0;
int index_tail = height.length - 1;
int area_max = 0;
while(index_head < index_tail)
{
int height_head = height[index_head];
int height_tail = height[index_tail];
int area = Math.min(height_head, height_tail) * (index_tail - index_head);
if(area > area_max)
area_max = area;
if(height_head > height_tail)
index_tail -= 1;
else
index_head += 1;
}
return area_max;
}
}
四. 引用
LeetCode: https://leetcode-cn.com/explore/orignial/card/all-about-array/232/two-pointers/969/