「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」
题目
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
示例 1:
输入:height = [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
来源:力扣(LeetCode)leetcode-cn.com/problems/co…
解题思路
容量计算公式为: S(i, j) = (j - i) * Math.min(height[i], height[j])
暴力破解
首先想到的是暴力破解,使用双循环分别求出每组垂直线内的容量,每次循环更新一次最大值。容量的大小取决于最短的垂直线的高度。暴力破解的时间复杂度比较差,力扣提交时会超时。
双指针
初始化双指针为 height 的两端,每循环一次小的一边向内缩进(因为长的缩进时容量会更小),当左边大于等于右边指针时结束循环,既可获取到最大容量。
代码实现
暴力破解
var maxArea = function(height) {
const len = height.length
let max = 0
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
//容量 = (j - i) * Math.min(height[i], height[j])
max = Math.max(max, (j - i) * Math.min(height[i], height[j]))
}
}
return max
};
双指针
var maxArea = function(height) {
let l = 0
let r = height.length - 1
let max = 0
//从两侧开始,短的一边向内缩进
while (l < r) {
max = Math.max(max, (r - l) * height[height[l] < height[r] ? l++ : r--])
}
return max
};
如有错误欢迎指出,欢迎一起讨论!