11. 盛最多水的容器

 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution:
    def maxArea(self, height: List[int]) -> int:
        """
        1.暴力求解
        for i in range(n):
            for j in range(n):
                l = x[i]-x[j]
                h = min(height[i],height[j])
                max_s = max(l * h,max_s)
        return max_s
        2.双指针法
        """
        n = len(height)
        l_left = 0
        l_right = n-1
        max_s = 0
        while l_left < l_right:
            h_l = height[l_left]
            h_r = height[l_right]
            s = (l_right - l_left) * (min(h_l,h_r))
            max_s = max(s,max_s)
            if h_l < h_r:
                l_left += 1
            else:
                l_right -= 1
                
        return max_s
            
        

优化后,用max和min会减慢速度

class Solution:
    def maxArea(self, height: List[int]) -> int:
        i, j, res = 0, len(height) - 1, 0
        while i < j:
            if height[i] < height[j]:
                res = max(res, height[i] * (j - i))
                i += 1
            else:
                res = max(res, height[j] * (j - i))
                j -= 1
        return res
'''
作者:jyd
链接:https://leetcode-cn.com/problems/container-with-most-water/solution/container-with-most-water-shuang-zhi-zhen-fa-yi-do/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
'''

证明

原文链接

0,1,2...指高低。s()=h*(x方向距离)

将0,1,2.换为任意值皆成立
遍历的情况.jpg

用h(i)表示第i条线段的高度,S(ij)表示第i条线段和第j条线段圈起来的面积。

可知 h(0) < h(7),从而S(07) = h(0) * 7。
所以我们应该选(1,7)

分析若选(0,6)会有什么情况:
    有S(06) = min(h(0), h(6)) * 6。    
    当h(0) <= h(6),有S(06) = h(0) * 6;
    当h(0) > h(6),有S(06) = h(6) * 6,S(06) < h(0) * 6。

由此可知,S(06)必然小于S(07)。

tree_1,h(0)<h(7),s=h(0)*8\\ tree_2\ of\ discarded,h(0)/h(6)\\ h(0)>h(6),s=h(6)*7<h(0)*7<h(0)*8\\ h(0)\leq h(6),s=h(0)*7<h(0)*8


递推下去,每次被舍弃掉的子节点必定小于父节点。所以不存在遗失最优解的情况。

在选中的子节点中寻找是否有比父节点 / 父节点的父节点 / 父节点的*大的点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值