【LeetCode Hot 100】Go语言题解:11. 盛最多水的容器(双指针法的优雅演练)
双指针法是一种能将O(n2)O(n^2)O(n2) 复杂度降低到 O(n)O(n)O(n) 的神技。LeetCode 第 11
题“盛最多水的容器”正是理解双指针移动逻辑、掌握“贪心思想”排除无效搜索空间的经典案例。
题目回顾
给定一个长度为 nnn 的整数数组 height。有 nnn 条垂线,第 iii 条线的两个端点是 (i,0)(i, 0)(i,0) 和 (i,height[i])(i, height[i])(i,height[i])。找出其中的两条线,使得它们与 xxx 轴共同构成的容器可以容纳最多的水。
示例:

输入: [1,8,6,2,5,4,8,3,7]
输出: 49
解释: 数组中索引 1(高度 8)和索引 8(高度 7)之间的容器面积最大。宽度为 8−1=78 - 1 = 78−1=7,高度取两者较小值 min(8,7)=7\min(8, 7) = 7min(8,7)=7,面积 7×7=497 \times 7 = 497×7=49。
解题思路分析:
为什么要用双指针?
计算容器面积的公式非常直观:Area=min(height[l],height[r])×(r−l)Area = \min(height[l], height[r]) \times (r - l)Area=min(height[l],height[r])×(r−l)如果要暴力枚举所有可能的组合,需要两层 for 循环,时间复杂度为 O(n2)O(n^2)O(n2)。但在 n=105n=10^5n=105 的数据规模下,这显然会超时。
我们需要一种更聪明的策略。
核心逻辑:移动“较短”的那一侧
我们设置两个指针 lll 和 rrr 分别指向数组的两端。此时,宽度 (r−l)(r - l)(r−l) 是最大的。接下来我们要向内收缩,宽度一定会减小。为了弥补宽度的损失,我们必须寻找更高的柱子。
- 如果移动长柱子: 容器的高度由短柱子决定,移动长柱子后,新高度绝不会超过原有的短柱子,而宽度又减小了,面积必然变小。
- 如果移动短柱子: 虽然宽度减小了,但我们有可能遇到一根更长的柱子,从而使得 min(height[l],height[r])\min(height[l], height[r])min(height[l],height[r])
增大,面积有可能增大。
这种“舍弃当前最短板”的操作,本质上是排除了所有以当前短柱子为边界的无效组合,从而在 O(n)O(n)O(n) 时间内找到最优解。
Go 语言代码实现
func maxArea(height []int) int {
var l int = 0
var r int = len(height)-1
var max0 = 0
for l!=r{
max0 = max(max0,min(height[r],height[l])*(r-l))
if(height[l]<height[r]){
l++
}else{
r--
}
}
return max0
}
更多推荐
所有评论(0)