题干
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明: 你不能倾斜容器。
题解 -- 双指针
这道题本质上是在一个整数列表中搜索两个点x, y,使得min(height[x], height[y]) * (y - x)最大。注意到(y - x)这一项最大就是当x和y分别处于整数列表的两端时,所以我们开始搜索时取到左右两个指针位于列表的两端。接下来的问题是指针如何移动,我们每一次移动都需要朝着乘积更大的方向移动,而每一次双指针向中间移动都会导致(y - x)变小,那么想要让乘积变大,我们就需要使min(height[x], height[y])这一项变大才行,
所以要让x, y中height更小的那一边向中间移动。
- 时间复杂度:O(n),
- 空间复杂度:O(1)
func min(a, b int) int {
if a < b {
return a
}
return b
}
func maxArea(height []int) int {
// 双指针位于列表两断
var i int
var j int = len(height) - 1
max := 0
for i < j {
cur := (j - i) * min(height[i], height[j])
if cur > max {
max = cur
}
// 将height小的那一边向中间移动
if height[i] < height[j] {
i++
} else {
j--
}
}
return max
}
func main() {
height := []int{1, 8, 6, 2, 5, 4, 8, 3, 7}
fmt.Println(maxArea(height))
height = []int{1, 1}
fmt.Println(maxArea(height))
height = []int{1}
fmt.Println(maxArea(height))
height = []int{}
fmt.Println(maxArea(height))
}