刷刷LeetCode放松放松---Container With Most Water
题目:
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.
审题:
容器的装水量由短板决定;
采用for循环遍历的话算法复杂度至少在O(n**2);
优秀方案1:
class Solution:
# @return an integer
def maxArea(self, height):
left=0
right=len(height)-1
result=0
while left<right:
result=max(result,(right-left)*min(height[left],height[right]))
if height[left]<height[right]:
left+=1
else:
right-=1
return result
此处采用左右指针从两边向中心移动的策略,每次更新完MaxArea之后,只保留该步中较高的墙壁,因为当指针从两侧向中心靠近时,只有较大的“短板”才有可能在下一步中构造出容积更大的容器。从而该策略也就减少了那些不可能带来比当前迭代步更大容积的容器构造过程。 也就是solution中说的: “If we try to move the pointer at the longer line inwards, we won't gain any increase in area, since it is limited by the shorter line”
优秀方案2:
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
MAX = 0
x = len(height) - 1
y = 0
while x != y:
if height[x] > height[y]:
area = height[y] * (x - y)
y += 1
else:
area = height[x] * (x - y)
x -= 1
MAX = max(MAX, area)
return MAX
方案2的思路和方案一相同,但实现上更有技巧性,方案2的每一次比较操作之后,同时更新了area和左右指针,减少了比较操作的次数,更加省时,通过调用time很容易验证这一点。