LeetCode - 盛最多水的容器 - 对撞指针

一. 题目描述

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (iai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (iai) 和 (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/

猜你喜欢

转载自blog.csdn.net/qq_28634403/article/details/87915398