About
好菜呀,我真的好菜呀,绝望,发现做题时思路不清晰是我最大的问题,总想着快点写出来,结果没想清楚就开始动手,也许面试时好多人没法手写代码也是这个原因吧。。。
求盛最多水的容器
题目描述
给定 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
解题思路
思路很简单,直接暴力求解,从数组左边开始遍历为第一个循环,以每个元素为左边的木板,然后从队列尾部开始遍历,以每个元素为右边的木板,求最大值。简单粗暴。
代码
class Solution:
def maxArea(self, height: List[int]) -> int:
length = len(height)
volume = temp = (0, 0)
try:
for i in range(length - 1):
if i > 0 and height[i] - height[volume[1]] <= volume[1] - i:
continue
for j in range(1, length - i):
if height[-j] <= height[i]:
volume = max(((length - j - i) * height[-j], i), volume)
else:
volume = max(((length - j - i) * height[i], i), volume)
break
return volume[0]
except BaseException:
return 0
解法2
上面的方法是采取单向收缩,速度比较慢,解法2采取双指针法,容器的左右木板同时向里收缩,求最大值,这样只需要遍历一遍数组就ok。
class Solution:
def maxArea(self, height: List[int]) -> int:
l, r, res = 0, len(height) - 1, 0
while l < r:
if height[l] < height[r]:
res = max(res, height[l] * (r - l))
l += 1
else:
res = max(res, height[r] * (r - l))
r -= 1
return res
虽然速度还是很慢,但是我没想出什么好的办法了,所以我是真的菜。。。
结束语
有时候做到困难的题也不会觉得很难,但有时候做到中等难度的题真的能让我想很久,我又是个很执拗的人,一道题做不出来什么都不想干,哎,希望能变聪明些吧。。。