leetcode11. Container With Most Water 盛水最多的容器

题目要求:

给一个数组,其中数组在下标i处的值为A[i],坐标(i,A[i])和坐标(i,0)构成一条垂直于坐标轴x的直线。现任取两条垂线和x轴组成四边形容器。问其中盛水量最大为多少?

思路一:暴力的双重循环

这种实现非常原始,在这里就不赘述了,时间复杂度为O(n2),在数据量较大的时候,性能很差

思路二:双指针

减少循环的核心思路是省去没有必要的遍历,并且确保所需的答案一定能被遍历到
假设现在有一个容器,则容器的盛水量取决于容器的底和容器较短的那条高
则我们可以从最大的底长入手,即当容器的底等于数组的长度时,则容器的盛水量为较短边的长乘底
可见 只有较短边会对盛水量造成影响,因此移动较短边的指针,并比较当前盛水量和当前最大盛水量。直至左右指针相遇。

主要的困惑在于如何移动双指针才能保证最大的盛水量被遍历到
假设有左指针left和右指针right,且left指向的值小于right的值,假如我们将右指针左移,则右指针左移后的值和左指针指向的值相比有三种情况

右指针指向的值大于左指针
这种情况下,容器的高取决于左指针,但是底变短了,所以容器盛水量一定变小

右指针指向的值等于左指针
这种情况下,容器的高取决于左指针,但是底变短了,所以容器盛水量一定变小

右指针指向的值小于左指针
这种情况下,容器的高取决于右指针,但是右指针小于左指针,且底也变短了,所以容量盛水量一定变小了

综上所述,容器高度较大的一侧的移动只会造成容器盛水量减小
所以应当移动高度较小一侧的指针,并继续遍历,直至两指针相遇。

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


        left = 0
        right = len(height)-1
        key = 0
        while left< right:
            key = max(key,(right-left)*min(height[left],height[right]))
            if height[left] < height[right]:
                left += 1
            else:
                right -= 1

        return key

你可能感兴趣的:(leetcode)