leetcode刷题记--> 11题解法(python解析)
题目定义
给定 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
来源:力扣(LeetCode)
链接: leetcode_11题.
解法一(暴力解法)
在解题方法中,由于使用的是暴力求解法,也就是从列表的第一个位置 i 进行遍历,然后固定住,再使用列表中的下一个元素 j 进行遍历,并且记录此时 i 与 j 元素的距离 x ,并求出在 i 元素和 j 元素两个元素的最小值 y , 将x与y相乘得到面积,并且一次循环,找到最大的面积。时间复杂度为O(n**2)
// An highlighted block
class Solution:
def maxArea(self, height):
'''暴力求解法
此方法在 leetcode中过不去 但是使用java可以过去
'''
if len(height)<2:
return 0
capacity = 0
for i in range(0,len(height)):
for j in range(i+1,len(height)):
x = j-i
y = min( height[i],height[j] )
capacity = max(capacity, y*x)
return capacity
解法二 (双下标法)
我们可以换个思维进行解析,可以将这个数组分为左右两个部分进行分别解析,首先我们将最左边的元素和最右边的元素进行作为我们初始的面积值,然后我们假设此时面积是最大的,但我们设置的指针开始向中间走,如果想让面积更大,那么只能让元素值变大,因为元素往中间走,那么这个面积的底就会变小,所以,不论我们将做元素和右元素哪个进行移动,面积的底都是一样的,所以,我们将元素比较大的值进行保留,将元素小的值进行舍弃,然后将小的值的方向的下标加1,依次进行移动,找出面积,并与,之前的最大的面积相比较,找出最大的面积,这样我们的元素列表只查询了一遍,并且也能找出最大的面积值,时间复杂度为O(n).
// An highlighted block
class Solution:
def maxArea(self, height):
'''双下标法'''
if len(height)<2:
return 0
left= 0
right = len(height)-1
capacity = 0
while left < right:
x = right - left
y = min(height[left],height[right] )
capacity = max(capacity,x*y)
if height[left]<height[right] :
left+=1
else:
right-=1
return capacity
测试
// An highlighted block
print(Solution().maxArea([1,8,6,2,5,4,8,3,7])) # 49
print(Solution().maxArea([1,1])) # 1
print(Solution().maxArea([1,2,4,3])) # 4