Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
本题是2Sum的升级版,要求从list中找出三个int使之相加等于0。我用的方法是定义一个twoSum的函数,遍历数组的同时调用该函数,便可达到计算threeSum的目的。也可以使用嵌套循环(说不定更快)。
- 判断特殊情况,list长度小于3直接返回空数组,等于3的话判断相加是否为0
- list长度大于3的情况下遍历list第一个到倒数第三个元素,遍历前排序
- 将当前元素的value和该元素后面部分的list切片作为参数传入twoSum函数
- 遍历twoSum返回值,将当前元素的value添加进去组成triplet,将triplet添加到res中
- 返回res
该方法的时间复杂度为O(n2),不过同样是O(n2),经过细节优化依然可以大幅度提升运行速度,比如预先排序后,twoSum可以使用nums的切片作为参数,而不用传入整个list,另外还可以省去最后的判断步骤if item not in res:
,直接append就行,因为经过排序和跳过相等的元素之后,不可能再出现重复的情况。经过努力,从6684 ms优化到2188 ms。
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def twoSum(nums, target):
res = []
i = 0
j = len(nums) - 1
while i < j:
if i > 0 and nums[i] == nums[i-1]:
i += 1
continue
if j < len(nums) - 1 and nums[j] == nums[j+1]:
j -= 1
continue
if nums[i] + nums[j] < target:
i += 1
elif nums[i] + nums[j] > target:
j -= 1
else:
res.append([nums[i], nums[j]])
i += 1
if res:
return res
else:
return None
res = []
l = len(nums)
if l < 3:
return []
if l == 3:
if sum(nums) == 0:
res.append(nums)
return res
else:
return []
nums.sort()
for i, v in enumerate(nums[0:l-2]):
if i > 0 and v == nums[i-1]:
continue
new_nums = nums[i+1:]
if twoSum(new_nums, 0-v):
doublet = twoSum(new_nums, 0-v)
for item in doublet:
item.append(v)
item.sort()
res.append(item)
return res