给你一个整数数组
nums,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、i != k且j != k,同时还满足nums[i] + nums[j] + nums[k] == 0。请你返回所有和为0且不重复的三元组。注意: 答案中不可以包含重复的三元组。
示例 1:
输入: nums = [-1,0,1,2,-1,-4]
输出: [[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入: nums = [0,1,1]
输出: []
解释: 唯一可能的三元组和不为 0 。
示例 3:
输入: nums = [0,0,0]
输出: [[0,0,0]]
解释: 唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000-10^5 <= nums[i] <= 10^5
代码
1.暴力超时
def threeSum(nums) :
nums.sort() # 排个序方便去重
n = len(nums)
ans = []
# 1.暴力
for i in range(n):
for j in range(i + 1 , n):
for k in range(j + 1 , n):
if i != j and i != k and j != k and nums[i] + nums[j] + nums[k] == 0:
ans.append([nums[i],nums[j],nums[k]])
t = list(set(tuple(r) for r in ans)) # 使用set去重先转为元组
return list(t)
2.双指针
def threeSum(nums) :
nums.sort() # 排个序方便去重
n = len(nums)
ans = []
for i in range(n-2):
# i最大n-3, 留够最后的j,k的位置n-1,n-2
if i > 0 and nums[i] == nums[i-1]:
# 起点重复的跳过
continue
if nums[i] > 0:
#排了序的,后面更大的数相加不满足==0
break
j = i + 1 # 双指针
k = n - 1
while j < k:
sums = nums[i] + nums[j] + nums[k]
if sums == 0:
ans.append([nums[i],nums[j],nums[k]])
j += 1
k -= 1
# 重复的就略过
while j < k and nums[j] == nums[j-1]:
j += 1
while j < k and nums[k] == nums[k+1]:
k -= 1
elif sums > 0:
# 大了,右指针左移,重复的就略过
k -= 1
while j < k and nums[k] == nums[k+1]:
k -= 1
else:
#小了,左指针右移,重复的就略过
j += 1
while j < k and nums[j] == nums[j-1]:
j += 1
return ans