枚举数组中所有可能的互不相同的三元组使其和为0:排序+双指针
先不考虑时间复杂度,最简单的想法是枚举所有三元组:
for i in range(n):
for j in range(i+1,n):
for k in range(j+1,n):
res.append([a[i],a[j],a[k]])
这样会有重复,那什么导致了重复呢?无非是两种情况:
[0,1,2]
和[2,0,1]
重复[0,1,2]
和[0,1,2]
重复
首先可以通过限制a<=b<=c
来除去第一个重复,具体操作是先对数组排序再枚举。
其次可以通过限制只有当前枚举的元素和上一个不相同来去除第二个重复。
这样得到的答案就是没有重复的了,但是O(N*3)还是太慢了。
又发现,当固定i
枚举j,k
时,设第一次满足条件时为j1,k1
,第二次为j2,k2
,由于j1<j2
则一定有k1>k2
,由此知可以同时枚举j,k
,也就是双指针。
可以这样理解,双指针就是在满足一定条件的情况下,把双重循环变为一次遍历。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
if n<3:
return []
nums.sort()
res = []
i=0
while i<n-2:
l = i+1
r = n-1
while l<r:
if nums[l]+nums[i]+nums[r]==0:
tmp = [nums[l],nums[i],nums[r]]
res.append(tmp)
while l<r and nums[l+1]==nums[l]:
l+=1
while l<r and nums[r-1]==nums[r]:
r-=1
l+=1
r-=1
elif nums[l]+nums[i]+nums[r]<0:
l+=1
else:
r-=1
while i<n-2 and nums[i]==nums[i+1]:
i+=1
i+=1
return res