Contain with most water Leetcode #11 题解[Python]

27 篇文章 1 订阅
24 篇文章 0 订阅
题目描述

Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.

大意是给一条从0开始的正整数数轴并且其长度为n,数轴上的第i个点对应着一个非零整数ai. ai的值的大小代表了这个点上立着一块高度为ai的隔板. 现在的问题是如何选取两个挡板构成一个容器, 使得该容器能装下最多的水.

注意: 容器不可倾斜并且n保证大于等于2.

解题思路


直观的解法无疑是肉身模拟, 用两层遍历的方式解决问题, 但这样一来, 复杂度就到了 O(n2) O ( n 2 ) , 并不尽如人意.

更快的解法自然是有的. 不妨这样想, 决定容器装水量无疑是它的绝对容积–即考虑到木桶效应的容积. 这时候计算装水量无非是简单的底*高, 底是隔板间的间隔, 高是其中较短的一块木板.

这里很明显的有两个变量, 底和高. 我们自然联想到采用控制变量的原则: 先固定其中一个量–或者是这个量的变化趋势, 再来讨论另一个量来简化计算.

注意到, 这一问题中, 假如我们从两头最边上的挡板开始取, 那么我们便可以控制底的变化趋势是递减的, 再来讨论高的变化–充满了变数的”高”.

由此自然得出了我们的 O(n) O ( n ) 算法:

  1. 从两头起, 计算底最大时的容积, 并维护和保持最大容积这个变量, 同时登记两块板中较短的那块板(容器高度)高度为最短挡板
  2. 从两边向中间移动, 显然这时底是递减的,, 要使得最大容积有变大的可能, 就要求最短挡板的高度变大. 因此从两边向中间移动时, 遇到比原来最短挡板还短的挡板直接跳过, 碰到更高的挡板时停止, 同时更新维护最大容积和最短挡板这两个值
  3. 重复Step 2, 直到两边都走到了中间会合. 算法停止并返回最大容积.

代码实现


给出Python的代码实现如下.

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        i = 0
        j = len(height) - 1
        water = 0
        while i < j:
            h = min(height[i], height[j])
            water = max((j - i) * h, water)
            while i < j and height[i] <= h:
                i = i + 1
            while i < j and height[j] <= h:
                j = j - 1
        return water

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值