[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%的用户
posted @ 2020-03-16 02:20  世界边境  阅读(165)  评论(0编辑  收藏  举报