leetcode11-盛水最多的容器
leetcode 11
思路
问题分析
拆解问题,面积 = 底 * 高
- 宽度:两个竖直线之间的距离,显然是 right - left
- 高度:容器的水位受限于较短的那根竖直线的高度,所以高度为 min(height[left], height[right])
本题其实很容易想到暴力解法,通过双重遍历,计算每一对竖直线所能形成的容器的面积,并记录最大面积。但这种方法的时间复杂度是 O(n²),效率较低,并且无法在leetcode中通过
优化解法-双指针法
- 由于容器的面积受制于最短的那根竖直线,所以优化的关键在于动态调整左右指针的指向,跳过不必要的比较
- 我们使用双指针的方式,初始化 left 指针在数组的开头,right 指针在数组的末尾,计算当前容器的面积:
- 如果 height[left] < height[right],则移动 left 指针,目的是尝试找到一个更高的左边竖直线,增加可能的面积。
- 如果 height[left] >= height[right],则移动 right 指针,尝试找到一个更高的右边竖直线。
- 每次移动指针时,都会计算并更新最大面积
为什么双指针法有效
- 双指针法通过始终选择最短的竖直线来决定移动哪一边指针。因为较短的那根竖直线是面积的瓶颈,只有尝试替换较短的线,才能可能增加容器的面积
- 如果我们不这么做,选择较长的线是没有意义的,因为更短的那条线限制了容器的容量
实现
var maxArea = function (height) {let left = 0, right = height.length - 1;let max = 0;while (left < right) {let min = Math.min(height[left], height[right])const area = (right - left) * min;max = Math.max(max, area)if (min === height[left]) {// 左边值更小left++} else {right--}}return max;
};