思路:1.先排序保证不重复以及减小复杂度 2. 左右双指针,左指针右移,右指针左移
代码实现:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
if n < 3:
return []
nums.sort()#先排序,保证不重复并且减少时间复杂度
res = []
# 左右双指针,时间复杂度O(n^2)
#三数相加等于0,那么先固定第一个数,后两个数相加等于定值,因此第二个数增加第三个数必定减小,左右双指针
for i in range(n-2):
if nums[i] > 0: #如果第一个数大于0,那么三数之和不可能等于0
break
if i > 0 and nums[i] == nums[i-1]:
continue #保证不重复 !使用continue
left = i + 1
right = n - 1
while left < right:
if nums[i]+nums[left]+nums[right]==0:
res.append([nums[i], nums[left], nums[right]])
while left < right and nums[left+1]==nums[left]: #!用while而不是if
left+=1
while left < right and nums[right]==nums[right-1]:
right-=1
left += 1
right -= 1
elif nums[i]+nums[left]+nums[right]>0:
right -= 1
else:
left += 1
return res
'''
# 时间复杂度O(n^2*log(n)),超时
for i in range(n-2):
if nums[i]>0:
break
for j in range(i+1, n-1):
tmp = -1*(nums[i] + nums[j])
left = j+1
right = n-1
while left <= right:
mid = (left+right)//2
print(mid)
if nums[mid]>tmp:
right = mid-1
elif nums[mid]<tmp:
left = mid+1
else:
ans = sorted([nums[i], nums[j], nums[mid]])
if ans not in res:
res.append(ans)
break
return res
'''
'''
# 暴力搜索,时间复杂度O(n^3)超时
res = []
for i in range(n-2):
for j in range(i+1, n-1):
tmp = -1*(nums[i] + nums[j])
for k in range(j+1,n):
if nums[k] == tmp:
ans = sorted([nums[i], nums[j], nums[k]])
if ans not in res:
res.append(ans)
return res
'''