题目描述
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题思路
- 先将给定 nums 排序,复杂度为 O(NlogN)O(NlogN)。
- 异常判断
- 因为 nums[j] > nums[i] > nums[k] >0 ,三个数中必须要有负数。
- 使用双指针 前后夹击,遇到相同的元素,则跳过
- 三数之和小于0,左边的指针i向右移动增大,并且要跳过所有的相同的元素
- 三数之和大于0,右边的指针j向左移动减小,并且要跳过所有的相同的元素
- 三数之和等于0,将组合添加到res,并且要跳过所有的相同的元素
代码
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res = []# 返回值
if len(nums) <3:# 异常判断
return []
for k in range(len(nums) - 2):
if nums[k] > 0: # 因为 nums[j] > nums[i] > nums[k]
break
if k > 0 and nums[k] == nums[k-1]:
continue # 跳过相同的元素
i,j = k +1 ,len(nums) - 1 # 双指针 前后夹击
while i < j :
s = nums[k] + nums[j] + nums[i] # 三数之和
if s < 0: # 三数之和小于0,左边的指针i向右移动增大,并且要跳过所有的相同的元素
i += 1j
while i < j and nums[i] == nums[i -1]:
i += 1i
elif s > 0: # 三数之和大于0,右边的指针j向左移动减小,并且要跳过所有的相同的元素
j -= 1
while i < j and nums[j] == nums[j + 1]:
j -= 1
else: # 三数之和等于0,将组合添加到res,并且要跳过所有的相同的元素
res.append([nums[k],nums[i],nums[j]])
i += 1
j -= 1
while i < j and nums[i] == nums[i - 1]:
i += 1
while i < j and nums[j] == nums[j + 1]:
j -= 1
return res
算法复杂度分析
-
时间复杂度为 :
- 数组排序
- 遍历数组
- 算个指针遍历 ,
- 总体
-
空间复杂度 :
- 指针使用常数大小的额外空间。