题目:
给你 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%的用户