【LeetCode】 盛最多水的容器 - 中等题我也不带怕

538 阅读1分钟

嗨!~ 大家好,我是YK菌 🐷 ,一个微系前端 ✨,喜欢分享自己学到的小知识 🏹,欢迎关注我呀 😘 ~ [微信号: yk2012yk2012,微信公众号:ykyk2012]

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

简单题重拳出击,中等题我也不带怕的!!今天来一道中等题,其实这道题编码很简单,但是这个思想很重要。

11. 盛最多水的容器(中等)

leetcode-cn.com/problems/co…

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai)
在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai)(i, 0)
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

在这里插入图片描述

【解法】暴力枚举

一拿到这题,不想思考就直接双重循环暴力枚举出所有结果,然后返回最大值即可。

/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    let maxArea = 0

    for(let i = 0; i < height.length - 1; i++){
        for(let j = i + 1; j < height.length; j++){
            let h = Math.min(height[i], height[j])
            let thisArea = (j - i) * h
            maxArea = Math.max(thisArea, maxArea)
        }
    }
    return maxArea
};

结果当然就是超时了!!!

image.png

【解法】双指针

暴力解法时间复杂度为O(N2)O(N^2),显然效率太低了。我们再仔细想想,真的有必要暴力枚举出所有的情况吗?

首先我们思考,容器中水的容量是由哪些因素组成的,就是 底 * 高 底就是两个垂直线下标之间的差,而高就是两条垂直线中最小的那一个。 我们拿两个指针ij分别指向两个垂直线,所以想得到盛最多水的容器,应该是ij距离尽可能远的情况下,找一个ij中小的那个也不是太小的...有点拗口

所以我们可以转换思路,我们将ij一开始就直接设置在数组的两端,计算当前可以容纳的水的容量。

接下来就要移动指针了,移动哪一个呢? 向内移动值小的那个指针。

为什么要这样做呢? 我们这样想,如果你移动值较大的那个指针,较小的指针肯定决定了未来高度的上限,而ij之间的距离会变小,也就是说,容量只会减不会增,移动大值的那个指针的所有操作都是不需要的。

所以我们总结一下

初始时,两个指针分别指向数组的两端,得到当前可以容纳的水的容量;每次移动一个指针,就是指向的值小的那个指针。

/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    let i = 0;
    let j = height.length - 1;
    let maxArea = 0;
    
    while(i<j){
        // 计算当前容量
        let thisArea = Math.min(height[i],height[j]) * (j - i);
        // 更新最大容量
        maxArea = Math.max(maxArea, thisArea);
        // 移动指针
        if(height[i] <= height[j]){
            i++;
        }else{
            j--;
        }
    }
    
    return maxArea;
};

image.png

最后我们再通过图示来证明我们方法的正确性

我们在移动指针的时候抛弃了很多的解,但是这些解是可以抛弃的解,不会影响结果的解

将本题的搜索空间用矩阵表示出来就是这样的【白色区域】

在这里插入图片描述

如果遍历所有的解【所有小方块】,就需要O(N2)O(N^2)的复杂度

通过本题的双指针来缩减搜索空间, 双指针最先得到的解是右上方的解

在这里插入图片描述

假设左边的 0 号柱子较短。代码中就是 i++; 对应于搜索空间,就是削减了一行的搜索空间,如下图所示。

在这里插入图片描述

排除掉了搜索空间中的一行之后,我们再看剩余的搜索空间,仍然是倒三角形状。

在这里插入图片描述

最终的动图如图所示

在这里插入图片描述

图片作者:nettee; 链接

最后,欢迎关注我的专栏,和YK菌做好朋友~