LeetCode 11.盛水最多的容器【中等】

57 阅读1分钟

题干

给定一个长度为 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))

}