LeetCode算法题(Go语言实现)_12
题目
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
一、代码实现
func maxArea(height []int) int {
maxWater := 0
left, right := 0, len(height)-1
for left < right {
// 计算当前容器面积
currentHeight := min(height[left], height[right])
width := right - left
maxWater = max(maxWater, currentHeight * width)
// 移动较矮的指针
if height[left] < height[right] {
left++
} else {
right--
}
}
return maxWater
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
二、算法分析
1. 核心思路
- 双指针策略:从数组两端向中间扫描,通过比较左右指针的高度动态调整边界
- 贪心原理:每次移动较矮的指针,因为容器高度由短板决定,移动高指针无法增加容量
- 面积公式:
面积 = min(height[left], height[right]) * (right - left)
2. 关键步骤
- 初始化指针:
left=0
,right=n-1
- 循环计算:每次迭代计算当前容器的储水量
- 指针移动:较低高度的指针向中间移动,尝试找到更高边界
- 终止条件:当
left >= right
时结束
3. 复杂度
- 时间复杂度:
O(n)
,单次遍历数组 - 空间复杂度:
O(1)
,仅使用固定变量
三、图解
四、边界条件与扩展
1. 边界处理
• 全零数组:[0,0,0]
→ 返回0(因高度限制)
• 单峰数组:如[1,3,6,4,2]
→ 正确识别最高边界组合
• 等值数组:[5,5,5]
→ 最大面积由最远距离决定
2. 算法对比
方法 | 时间复杂度 | 优势 | 适用场景 |
---|---|---|---|
双指针法 | O(n) | 最优解,空间效率高 | 常规及大数据量 |
暴力枚举 | O(n²) | 逻辑简单 | 小规模数据 |
动态规划 | O(n²) | 可记录中间结果 | 特殊优化场景 |
五、总结
- 核心创新:通过移动短板的策略,在宽度递减的过程中寻找高度增益的可能性
- 数学证明:
设最优解为(i,j)
,双指针法必会遍历到该解。若i
先被移动,则必有height[i] < height[j']
(j'
为当时右指针),这与最优解矛盾 - 应用场景:实时水位监测系统、图形学中的最大区域计算等