盛最多水的容器
使用的是两次遍历,时间复杂度是O(n^2)
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
max_volume=0
for i in range(len(height)):
for j in range(i+1,len(height)):
volume=(j-i)*min(height[i],height[j])
max_volume=max(volume,max_volume)
return max_volume
使用双指针,一个从头,一个从尾,因为两指针i,j距离越大越好,i和j数组值小的那个向中间移动一格。时间复杂度就会只有O(n)
i,j=0,len(height)-1
max_volume=0
while i<j:
volume=(j-i)*min(height[j],height[i])
max_volume=max(max_volume,volume)
if height[i]<=height[j]:
i+=1
else:
j-=1
return max_volume
15. 三数之和
除了暴力解,可以用排序+双指针, k遍历数组,i=k+1,j=len(nums)-1,当和小于0说明i应该增大,和大于0说明j应该减小,时间复杂度为O(n^2)
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
l=len(nums)
res=[]
k=0
for k in range(l-2):
if nums[k]>0:
break
if k>0 and nums[k]==nums[k-1]:
continue
i=k+1
j=l-1
while i<j:
s=nums[k]+nums[i]+nums[j]
if s<0:
i+=1
while i<j and nums[i]==nums[i-1]:
i+=1
elif s>0:
j-=1
while i<j and nums[j]==nums[j+1]:
j-=1
else:
res.append([nums[k],nums[i],nums[j]])
i+=1
j-=1
while i<j and nums[i]==nums[i-1]:
i+=1
while i<j and nums[j]==nums[j+1]:
j-=1
return res
42. 接雨水
双指针,每一列找左边最大,和右边最大,左右当中的短板就是倒水的极限
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
volume=0
for i in range(1,len(height)-1):
max_left=0
for j in range(i-1,-1,-1):
max_left=max(max_left,height[j])
max_right=0
for j in range(i+1,len(height)):
max_right=max(max_right,height[j])
min_one=min(max_left,max_right)
if min_one>height[i]:
volume+=min_one-height[i]
return volume
再精简一点:
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
volume = 0
left_max = 0
right_max = 0
left = 0
right = len(height) - 1
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
volume += left_max - height[left]
left += 1
else:
if height[right] >= right_max:
right_max = height[right]
else:
volume += right_max - height[right]
right -= 1
return volume