版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012343179/article/details/89787846
1.将数组排序
2.定义三个指针,i,j,k。遍历i,那么这个问题就可以转化为在i之后的数组中寻找nums[j]+nums[k]=-nums[i]这个问题,也就将三数之和问题转变为二数之和
注意:因为排过序了,所以当nums[i+1]=nums[i]时就不用考虑了。
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def twoSum(nums,sum_num):
d={}
result=[]
for i,num in enumerate(nums):
if d.get(sum_num-num)!=None:
result.append([nums[d.get(sum_num-num)],nums[i]])
if d.get(num)==None:
d[num]=i
return result
nums.sort()
res=set()
for i,num in enumerate(nums):
if i > 0 and nums[i] == nums[i-1]:
continue
result=twoSum(nums[i+1:],-num)
if len(result)>0:
for r in result:
item=(num,r[0],r[1])
res.add(item)
return res
双指针做法:
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
最快做法:
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
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:
#a+b+c = 0
#a+b = -c
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