【LeetCode】11.Container With Most Water(Python)

Problem

给定n个非负整数a 1,a 2,…,a n ,其中每个表示坐标(i,a i)处的点。绘制n条垂直线,使得线i的两个端点位于(i,a i)和(i,0)。找到两条线,它们与x轴一起形成一个容器,这样容器就含有最多的水。
注意: 您可能不会倾斜容器,n至少为2。
LeetCode11
上面的垂直线由数组[1,8,6,2,5,4,8,3,7]表示。在这种情况下,容器可容纳的最大水面积(蓝色部分)为49。

例:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49

Algorithmic thinking

解法一:暴力法,O(n^2),取到最大值

解法二:两指针方法
这种方法背后的直觉是线之间形成的区域总是受到较短线高度的限制。此外,线越远,获得的区域越多。
我们取两个指针,一个在开头,一个在数组的末尾,构成行的长度。此外,我们维持一个变数maxarea存储到目前为止获得的最大面积。在每一步,我们找出它们之间形成的区域,更新maxarea并且由一个步骤移动指针指向朝向另一端的短线。

这种方法如何运作?
最初我们认为构成外部最多线的区域。现在,为了最大化面积,我们需要考虑较大长度的线之间的区域。如果我们试图将指针向内移动更长的线,我们将不会获得任何面积增加,因为它受到较短线的限制。但是,尽管宽度减小了,但根据相同的论点,移动较短线的指针可能会变得有利。这样做是因为通过移动较短线的指针获得的相对较长的线可以克服由宽度减小引起的面积减小。

Python3 solution

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


class Solution:
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """

        """ 
        方法一:暴力法,可运行。但是提交超时,不可通过。
        """
        # max_ = 0
        # for i in range(len(height)):
        #
        #     for j in range(i+1, len(height)):
        #         max_ = max(max_, min(height[i], height[j]) * (j - i))
        #
        # return max_

        """
        方法二:分别从列表左右两端遍历(while),面积=短边*距离,哪边短遍历时+1,因为短的已达最大值。
        """
        max_area = 0
        i = 0
        j = len(height) - 1
        while i < j:
            width = j - i
            length = min(height[i], height[j])
            volume = width * length
            if max_area < volume:
                max_area = volume
            if length == height[i]:
                i += 1
            else:
                j -= 1
        return max_area


if __name__ == '__main__':
    integer_list = [1, 3, 3, 9, 12, 1, 2, 43, 2, 23, 2, 2, 23, 23, 23, 2]
    result = Solution().maxArea(integer_list)
    print(result)


Summary

我们必须最大化可以在垂直线之间形成的区域,使用较短的线条作为长度,并且线条之间的距离作为形成区域的矩形的宽度。

解法二复杂性分析:
时间复杂度: O(n)单程。
空间复杂度: O(1)使用恒定空间。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值