题解 | #盛水最多的容器#

盛水最多的容器

https://www.nowcoder.com/practice/3d8d6a8e516e4633a2244d2934e5aa47

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param height int整型一维数组 
     * @return int整型
     */
    public int maxArea (int[] height) {
        // write code here
        int left=0;
        int right=height.length-1;//定义左右指针
        int max=0;//记录题解的最大值
        while(left<right){//循环结束的条件
        int v=Math.min(height[left],height[right])*(right-left);//得到边界体积
        max=Math.max(v,max);//看是否需要更新最大体积
        if(height[left]>height[right]){//判断指针的走向
            right--;
        }else{
            left++;
        }
        }
        return max;//最后返回记录的最大值即可
    }
}

---->我们首先看一个例子,:以【6,2,5,4】举例

一开始的边界体积是3(长)×4(高)=12

--->然后我们固定以短的边界(高为4的)为一条边,与其他线(5,2,6...)组成一个容器,

--->我们会得到一个规律:那就是在一个区间中,固定使用短的那一条线为一条边,以其它的线为另外一条边,得到的容器体积一定是小于我们一开始(边界体积)的体积的

证明:主要是利用了木桶效应,容积取决于短的板

--->然后我们就可以用这个为跳板来推到整个大的区间

---->先来个整体的实现思路

定义两个指针,一个指向头,一个指向尾,此时可以得到一个体积(边界体积),记录下来,

这个时候就可以利用到上面的规律了,短的那一端指针可以舍弃了,因为以他为边,去和其他线匹配,都小于一开始的体积(边界体积·)

--->接下来让短的那一端的指针++或--(左边++,右边--)

得到下一个边界(left,right),然后记录这个边界体积,然后重复上述步骤,直到两个指针相遇

最后我们求我们得到的边界体积中的最大值即可

--->解释一下为什么,

从一开始的边界,我们根据规律把短的那一条边的匹配(与区间内的其它线组成容器)给省略了,因为都小于边界体积

然后让短的指针--或++

--->因为是一次走一步,,每次去掉一根线,当指针相遇的时候,它们一定走过了所有的线,即我们每次去掉的线都和其他线匹配过了(只是因为规律,我们没有算而已,但是它一定小于边界)

--->这里我们可能会想,若左边的指针在2下标处,而右边的指针在6下标处(做个假设),此时要把右下标舍弃--,那么右边下标跟边界里面的匹配肯定小,但是右边的线还没有跟2下标之前的匹配过呢,你就省略了,是不是漏了

--->其实没有漏,你想啊,你的left是怎么走到2下标的,

是不是也是把1,8当做了短的,然后舍弃过了,既然当做过短的,那么1,和8有没有和right匹配过?肯定的啊,所以之前就匹配过了,也是向内匹配,小于边界值,而边界值已经被记录了,所以不用考虑了

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务