Description:
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]
]
思路:
前面我们做过Two Sum的问题,这里会想到能不能先固定一个数a,那么就变成了target = - a 的Two Sum的问题,时间复杂度是
O
(
n
2
)
O(n^2)
O(n2)。实际证明原来使用hash的方法得到结果有重复,并且会TLE。
换种思路,因为不需要记录下标,可以对数组进行排序。假设某个位置的数字为a,需要从后续数组中找到两个数b、c满足b+c=-a。因为此时数组为已排序,因此可以用两指针分别中后续数组的两端往中间找,指针遇到重复的数字直接跳过,就避免了重复结果的出现。时间复杂度仍然是 O ( ( n − 1 ) + ( n − 2 ) + . . . 1 = n ( n − 1 ) / 2 ) = O ( n 2 ) O((n-1)+(n-2)+ ... 1 = n(n-1)/2) = O(n^2) O((n−1)+(n−2)+...1=n(n−1)/2)=O(n2)
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
nums.sort()
n = len(nums)
for i in range(n-2):
# 剪枝,该位置数为正数,那么后面所有数都大于零,三数和不会等于零
if nums[i] > 0: break
# 遇见重复值跳过
if i > 0 and nums[i] == nums[i-1]: continue
# 搜索两个数从当前循环固定值之后的数组中寻找,避免重复
low = i + 1
high = n - 1
while low < high:
cursum = nums[low] + nums[high] + nums[i]
if cursum == 0:
res.append([nums[i], nums[low], nums[high]])
# 跳过重复数
while low < high and nums[low] == nums[low+1]:
low = low + 1
while low < high and nums[high] == nums[high-1]:
high = high - 1
high = high - 1
low = low + 1
elif cursum > 0:
high = high - 1
else:
low = low + 1
return res