LeetCode11-盛最多水的容器 | 算法练习系列

423 阅读2分钟

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

前言

今天来一道有意思的算法题--盛最多水的容器,看到这个题目我就想到了以前看到过的短板效应也叫做木桶原理,这个原理就是你盛水的最大量不取决于你木桶的最长板,而取决于木桶的最短板,哈哈哈,不多说了,直接上题目。

题目描述

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

说明:你不能倾斜容器。

示例 1:

image.png

输入:[1,8,6,2,5,4,8,3,7]

输出:49

解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = [1,1]

输出:1

示例 3:

输入:height = [4,3,2,1,4]

输出:16

示例 4:

输入:height = [1,2,1]

输出:2

解题思路

  • 本题的主要思想就是盛水的最大容量取决于最短的那个柱子,想明白了这点问题就解决了一大半
  • 本题的解法是使用双指针,一个指向数组头部,一个指向尾部,依次判断左右指针中的最小值和两个指针之间的距离的乘积,然后判断左右指针那个值更小,舍弃小的,移动指针
  • 至于为什么这样操作就可以,下面我们来解释一下,假设左右指针分别指向的数是x,y,两个指针之间的距离是t,那么容量就是Math.min(x,y)*t,假设x<=y,这时,不论y如何移动新的容量都会小于移动前的容量,因为t在变小,x不变
  • 这时我们就可以舍弃原来左指针指向的位置了,也就是移动左指针
  • 也就是说,点比较两个指针指向的数的时候,比较小的那个数已经注定不能成为最大容量的边界了,下面上代码
/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    let left = 0 
    let right = height.length-1
    let maxCapacity = 0//最大容量
    let capacity = 0//每次移动之后的容量
    while(left < right){
        capacity = Math.min(height[left],height[right])*(right-left)
        maxCapacity = Math.max(maxCapacity,capacity)
        if(height[left]<height[right]){
            left++
        }else{
            right--
        }
    }
    return maxCapacity
};

LeetCode运行结果

结果.PNG

总结

这道题目挺有意思的,不仅是道算法题,还很有哲理,努力向前,gogogo