目录
题目链接
问题描述
给定包含n个整数的数组nums,对于nums中的元素a,b,c,找出nums中所有满足a + b + c = 0的元素组合[a,b,c]并返回,返回的元素list不可重复。
示例
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
输入:nums = []
输出:[]
输入:nums = [0]
输出:[]
解决思路
将3Sum问题转化为2Sum问题,即找到所有满足(b+c)= -a 的非重复元素组合。
对nums数组升序排序并遍历,对于nums中的每个元素nums[i],都去解决一个扩展后的2Sum问题:搜索[i+1:len(nums)]索引范围内的两个元素nums[s]和nums[e],使其满足nums[s]+nums[e] = -nums[i]。其中s和e相当于对撞指针,从两头向中间进行遍历。
从头开始遍历nums数组时,如果nums[i] > 0 就break跳出。因为升序过后nums[e] >= nums[s] >= nums[i],因此如果nums[i]大于0,索引大于i的数组元素一定都大于0,那么对于当前元素nums[i]及在nums[i]之后的元素都无法找到三个元素值相加为0的结果。
为了避免重复,需要注意几个问题:
1、遍历nums数组时,如果当前遍历到的nums[i] = nums[i-1],就跳出当前循环继续下一次循环。
因为在遍历到nums[i-1]时,会在 [i:len(nums)] 范围内搜索,遍历到nums[i]时,会在 [i+1:len(nums)] 范围内搜索,如果nums[i] = nums[i-1],那么遍历到nums[i]时的搜索结果一定是包含在遍历到nums[i-1]时的搜索结果内的。因此为了避免重复,需要排除这种情况。
2、要从[i+1:len(nums)]索引范围内搜索,而不是从头开始搜索。
举个例子,设有0<k<i<j<len(nums),且nums[k]+nums[i] +nums[j] = 0。如果遍历到nums[i]时,从头开始搜索,就会找出nums[k]和nums[j]两个元素,三个元素组成[nums[i],nums[k],nums[j]]。但是在此之前遍历到nums[k]时,也能找到[nums[k],nums[i],nums[j]]三个元素组合,因此会造成重复。
3、在对nums数组升序排序后,数组中的相同元素索引是相邻的。在[i+1:len(nums)]索引范围搜索时,如果找到s和e满足nums[s]+nums[e]+nums[i] = 0后左指针s仍小于e,并且出现nums[s] = nums[s+1]或nums[e] = nums[e-1],为了避免重复,需要通过指针移动越过相同元素。
举个例子,设排序后数组为[-1,-1,-1,0,1,2,2],对于nums[0],当s = 1,e = 6时,就满足nums[0] + nums[1] + nums[6] = 0。继续搜索时如果直接令s =2,e = 5,发现nums[2] + nums[4] + nums[5] = 0,会造成重复。
Python实现
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
return_list = []
N = len(nums)
if(N<3):
return return_list
nums.sort()
for i in range(0,N-2):
if(nums[i] > 0):
break
if i > 0 and nums[i] == nums[i-1]:
continue
target = nums[i] * -1
s = i+1
e = N-1
while(s < e):
if(nums[s]+nums[e] < target):
s += 1
elif(nums[s]+nums[e] > target):
e -= 1
else:
return_list.append([nums[s],nums[e],nums[i]])
while s < e and (nums[s] == nums[s+1]):
s += 1
while s < e and (nums[e] == nums[e-1]):
e -= 1
s += 1
e -= 1
return return_list
算法性能
算法的时间复杂度为O(n^2),空间复杂度为O(1)
Runtime: 500 ms, faster than 98.54% of Python online submissions for 3Sum.
Memory Usage: 16.8 MB, less than 57.91% of Python online submissions for 3Sum.