LeetCode 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

思路

把容器作为一个长方形,我们都知道长方形的面积等于长x宽,这里

长 = j-i(j,i为index)

宽 = [n1,n2,n3...]

所以面积最大为=max{[j-i] * n}

方法一:

依次按index比较,取所有情况的最大值,但是时间超时,虽然想法笨了点,但是方案是可行的,也是一种思路。

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        length = len(height)
        res = 0
        for i in range(length):
            for m in range(length):
                if  m >i: #shift m,i只与比其大的数取比较
                    if height[i] <=height[m]:  #正序,取i作为宽,index之差为长
                        res = max(res,(m-i)*height[i])
                    elif height[i]>=height[m]: #逆序,取m作为宽,index之差为长
                        res = max(res,(m-i)*height[m])
        return res
 	#或者用while循环
	for i in range(length):
              n = length -1
              while (n>i):
                     if height[i]<=height[n]:
                          res = max(res,(n-i)*height[i])
                      elif height[i]>=height[n]:
                          res = max(res,(n-i)*height[n])
                          n = n-1
        return res

方法二:

方法一中,2个循环累积遍历的时间太长,要想办法减少该循环,所以得换个思路。可是 想了一下,不管怎么样,都需要找长度和高度最大的情况,但是我并不知道他们的乘积谁最大,所以还是得去循环去找,然后循环比较,这样看,和方法一的思路是一样的,应该还是超时。所以只好参考评论题解寻找最优解。

本题是一道经典的面试题,最优的做法是使用「双指针」。如果读者第一次看到这题,不一定能想出双指针的做法

默念三遍,我是猪,我是猪,我是猪。就算没有想到双指针,我也应该要去想怎么去减少循环次数,也就是最大有效面积,说不准能想到移动右边距的情况,可是思维还是僵在之前的点子上了,不服不行呀,解题思路都是培养出来的,没错,继续加油。

先解释一下为什么可以用左右双指针移动来计算(摘自评论的一句总结)。

--->矮柱子选取后如果移动高柱子的话面积是一定会减小的,因为长度距离在变小的时候,此时高度只能小于或等于矮的柱子。因此只能移动矮的柱子这边才有可能使得高度比矮柱子大

其实仔细思考一下,不难发现这个结论。但是我是猪,哈哈哈。

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        length = len(height)
        n = length-1
        res = 0
        i = 0
        while (n>i):
            if height[i] <=height[n]:
                res = max(res,(n-i)*height[i])
                if i+1 < length:
                    i +=1
            elif height[i] >height[n]:
                res = max(res,(n-i)*height[n])
                if n >= 1:
                    n -=1
        return res

执行用时 :44 ms, 在所有 Python 提交中击败了47.89%的用户

内存消耗 :13.5 MB, 在所有 Python 提交中击败了8.33%的用户

原文地址:https://www.cnblogs.com/xiaoqiangink/p/12970964.html