[LeetCode-Golang] 11. 盛最多水的容器
题目
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
容器盛水的面积 = 底边长 * 两条垂直线最短的长度
该题为求最大面积
当两条垂直线位于容器两端,底边长最大,并不意味着面积最大,因为两条垂直线不在两端。虽然底边长变小,但只要两条垂直线最短的长度足够大,依然可以面积最大。
用双指针分别指向数组第一个元素和最后一个元素,求相应的面积,并与之前的最大值比较。
指针往中间移动,底边长变小,只有短木板高变大,才有可能面积变大,因此移动短木板的指针,这样原来的长木板才可能变成移动后的短木板。
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
代码
func maxArea(height []int) int { // 双指针分别指向数组第一个元素和最后一个元素 l, r := 0, len(height)-1 // ans存储所求的最大值 ans := 0 for l < r { // 面积=底边长*短木板的高,指针往中间移动,底边长变小,只有短木板高变大,才有可能面积变大 // 因此移动短木板的指针,这样原来的长木板才可能变成移动后的短木板 if height[l] < height[r] { // 如果当前面积>ans,更新ans ans = maxInt(height[l] * (r-l), ans) // 短木板的指针向中间移动 l++ } else { ans = maxInt(height[r] *(r-l), ans) r-- } } return ans } func maxInt(a, b int) int { if a > b { return a } return b }
执行结果
执行用时 :16 ms, 在所有 Go 提交中击败了79.68% 的用户
内存消耗 :5.8 MB, 在所有 Go 提交中击败了73.26%的用户