目录
问题
给定 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
解题思路
分析:这题,题目中感觉有盲点:容积的定义计算模糊。看了官方的题解,准确的题目,应该是求解给定的垂直线间与坐标轴构成的矩形区域的面积最大。考点大概就是木桶原理,矩形的高度由较短的那个垂线段决定。
1)一种简单的实现方法:即暴力实现,但算法的时间复杂度太高:。
2)这里我们分析另一种实现方法——所谓的双指针实现:
a. 在给定的垂直线段构成的数组,分别在开头和结尾,放上标记left和right(初始值对应数组的开始结尾的小标);
b. 然后求解这两垂直线间与坐标轴构成的矩形区域面积,矩形的高度即为较短的那个垂线段值,宽度为right-left,判断比较存储每次计算得到的面积值和当前记录的最大面积值中的最大值;
c. 之后,如果是left标记的值小于right标记的值,则left=left+1,否则,right=right-1;
数组遍历一遍即可得到结果,whle循环实现,条件即为left<right。对于输入的数组长度小于2,即特殊情况的处理,返回0即可。
详细过程描述,如上分析,程序具体如下:
python具体实现
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
if len(height)<2: # 数组长度的特殊情况
return 0
# 双指针实现
left,right = 0,len(height)-1
maxArea = 0 # 记录最大的矩形面积
while(left<right):
tempArea = min(height[left],height[right])*(right-left) #当前遍历到的矩形面积
if tempArea>maxArea: # 记录最大值
maxArea = tempArea
if height[left]>height[right]: #双指针的移动方式
right =right - 1
else:
left =left + 1
return maxArea
题外话
这道题,隐含着另一部分的数学原理,需要认真体会,不然还真就会暴力处理了。
一遍搞过!