力扣第十一题-盛最多水的容器

212 阅读1分钟

这是我参与更文挑战的第8天,活动详情查看: 更文挑战

前言

力扣第十题 盛最多水的容器 如下所示:

image.png

一、思路

先理解一下题目的意思,就是求一个最大的面积。

严谨一点,用数学中的思想来表示一下
假设数组为 a1,a2,...,an ,现有 ai、aj(i < j) 两个数,求 Min(ai, aj) * abs(i - j)
Min(ai, aj) * (j - i)j - i 表示容器底边长,Min(ai, aj) 表示容器的高

这一题需要想明白一点,怎么样才能面积最大呢?
其实很简单,两块板子相距越远,板子越高,得到的面积也就会越大

那么就可以有一个大概的思路了:从两端向中间靠近,丢弃矮的板子。
为什么是这样呢?

前提:i < j
假设 ai < aj,面积为 ai * (j - i)
假设右板子移动到了新位置 k (i < k < j),新面为 Min(ai, ak) * (k - i)
Min(ai, ak) <= ai,且 (k-i) < (j - i),易知新面积会小于之前的面积
也就是说,当矮板子固定时,无论如何移动都不会得到更大的面积,所以需要丢弃矮板子

二、实现

代码实现

思路有了,实现起来还是很容易的。此处可以使用双指针法

变量说明: left:左边界 right:右边界 ret:面积结果

/**
 * 此题采用双指针遍历即可
 */
public int maxArea(int[] height) {
    int left = 0;
    int right = height.length -1;
    int ret = 0;
    for (int i=0; i<height.length-1; i++) {
        ret = Math.max(ret, Math.min(height[left], height[right]) * (right-left));
        // 如果左边大
        if (height[left] > height[right]) {
            right --;
        } else {
            left ++;
        }
    }
    return ret;
}

测试代码

测试代码如下所示:

public static void main(String[] args) {
    int[] height = {1,8,6,2,5,4,8,3,7};
    int ret = new Number11().maxArea(height);
    System.out.println(ret);
}

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥