给定 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.暴力法:
从左起选中一条定边,之后for遍历右侧比较,右侧短就取右这个边为高,右侧长就取左边那个定边为高。
【卡壳点:注意左边最开始[i]这个边要定住 左侧这个定边不动,右侧动和这个左侧定边比】【关键在“定”字】
`def maxArea(height):
n = len(height)
max_ans = 0
for i in range(n): # 0-3
row = 0
col = 0
for j in range(i+1, n): # 1-3
row += 1
if height[j] >= height[i]:
col = height[i]
elif height[j] < height[i]:
col = height[j]
max_ans = max(max_ans, row*col)
return max_ans
2.双指针法:
1)核心思想:要满足宽尽可能长并且长也尽可能长 ,
但是最开始是宽最长,缩短宽让高变长,得出的多个长方形面积由于虽然高长了但是宽短了,所以面积不一定比之前变大还是减小了,所以要存入list必出最大的。【我用for循环顺带就max了,底层原理一样,将空间复杂度由n优化→1】。
2)为什么要短边向长边的方向移动?
因为 要是移动长边向短边方向移动的话:
2.1】要么高出短边但要取短边被制约了,肯定面积变小
2.2】要么低于短边,肯定面积更小了
def maxArea2(height):
n = len(height)
left_pos = 0
right_pos = n-1
S = 0
max_S = 0
while left_pos < right_pos:
row = right_pos - left_pos
if height[left_pos] < height[right_pos]:
S = height[left_pos] * row
left_pos += 1
elif height[left_pos] >= height[right_pos]:
S = height[right_pos] * row
right_pos -= 1
max_S = max(max_S, S) # 注意这些高长的多个也不知道哪个是最大的! 仍旧要list存住比出最大的(我这里用max实现的)
return max_S