给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解法一:Leetcode上目前用时最短的
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
# res = []
# nums.sort()#先排序可以去重复
# length = len(nums)
# for i in xrange(length-2): #最后的两个,和倒数第三个组成组合
# if nums[i]>0:
# break #因为已经排序了,所以到大于零的位置,之后的数字都是大于零的,肯定没有符合条件的组合了
# if i>0 and nums[i]==nums[i-1]:
# continue #这种就是说,前面已经尝试过,如果成功了这次会重复,没成功,这次也没必要做了
# l, r = i+1, length-1 #双指针开始遍历
# while l<r:
# total = nums[i]+nums[l]+nums[r]
# if total<0: #因为排序了,所以如果小于零,那么我们移动到更大的地方
# l+=1
# elif total>0: #排序的,所以我们往更小的方向移动
# r-=1
# else: #等于0符合要求
# res.append([nums[i], nums[l], nums[r]])
# #方式重复操作,左右都移动到不重复的数字
# while l<r and nums[l]==nums[l+1]: #[6]
# l+=1
# while l<r and nums[r]==nums[r-1]: #[6]
# r-=1
# l+=1
# r-=1
# return res
# a+b+c = 0
# a+b = -c
num_dict = {}
res = []
for i in nums:
if i in num_dict:
num_dict[i] += 1
else:
num_dict[i] = 1
pos = [i for i in num_dict if i>0]
neg = [i for i in num_dict if i<0]
neg.sort()
#特殊情况的妙用
if 0 in num_dict and num_dict[0]>=3:
res.append([0,0,0])
for i in pos:
for j in neg:
k = -i-j
if k in num_dict:
if (k==i or k==j) and num_dict[k]>=2:
res.append([i,k,j])
elif j<k<i:
res.append([i,k,j])
if k<j:
break
return res
解法二: 来源于https://www.twblogs.net/a/5c4b2590bd9eee6e7e06c45e/zh-cn
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort() #先对数组进行排序
res = []
for i in range(len(nums)-2): #先确定第一个数,因为总共要有3个数,所以只能循环至倒数第三个数
if i > 0 and nums[i] == nums[i-1]: #如果后面的数和前面的相同,为避免重复答案,跳过这次循环
continue
j = i + 1;k = len(nums) - 1 #对剩下的两个数设置首尾指针
while j < k:
s = nums[i] + nums[j] + nums[k]
if s < 0:
j = j + 1 #当前和比0小,需要增加当前的和,j右移
elif s > 0:
k = k - 1 #当前和比0大,需要减小当前的和,k左移
else:
res.append((nums[i],nums[j],nums[k])) #找到满足条件的数
while j < k and nums[j] == nums[j+1]: #左边移动到相同连续数字的最右端
j = j + 1
while j < k and nums[k] == nums[k-1]: #右边移动到相同连续数字的最左端
k = k - 1
j = j + 1;k = k -1 #上面的操作结束后,两个指针所指的值只是位于相同值的末端,值本身没有变化本身,需要继续移动到不同数字上
return res
解法三:https://www.cnblogs.com/chruny/p/4820473.html
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
size = len(nums)
ans = []
if size <= 2:
return ans
nums.sort()
i = 0
while i < size -2:
tmp = 0 - nums[i]
j = i + 1
k = size -1
while j < k:
if nums[j] + nums[k] < tmp:
j += 1
elif nums[j] + nums[k] > tmp:
k -= 1
else:
ans.append([nums[i],nums[j],nums[k]])
j += 1
k -= 1
while j < k:
if nums[j] != nums[j - 1]:
break
if nums[k] != nums[k + 1]:
break
j += 1
k -= 1
i += 1
while i < size - 2:
if nums[i] != nums[i - 1]:
break
i += 1
return ans