给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解法 1
暴力法,分三层遍历每个元素 i、j、x,并查找是否存在 i + j + x = target 的目标元素,若存在则加入结果数组,注意每层遍历开始和结束的位置。
def three_sum(nums):
if len(nums) < 3:
return []
nums.sort()
res = set()
for i in range(0, len(nums) - 2):
for j in range(i + 1, len(nums)-1):
for x in range(j+1,len(nums)):
if nums[i]+nums[j]+nums[x]==0:
res.add((nums[i],nums[j],nums[x]))
return list(map(list, res))
时间复杂度:, 对于每个元素,都需要遍历数组来寻找它所对应的目标元素,这将耗费 的时间。因此 3 个元素需要三层遍历,时间复杂度为
空间复杂度:, 用于存放结果的数组不超过 个元素。
解法 2
首先对输入数组排序,方便去重。第一、第二个元素通过两层遍历得到,分别是 v 和 x,判断哈希表 d 中是否存在符合条件的第三个元素,即 0 - v - x,若不存在则将当前元素 x 存入哈希表 d,这里有个优化手段是,当 v 和上一个元素相等时,则直接忽略,避免重复计算,也达到了结果数组去重的目的。注意每层遍历开始和结束的位置。
def three_sum(nums):
if len(nums) < 3:
return []
nums.sort()
res = set()
for i, v in enumerate(nums[:-2]):
if i >= 1 and v == nums[i - 1]:
continue
d = {}
for x in nums[i + 1:]:
if -v - x in d:
res.add((v, x, -v - x))
else:
d[x] = 1
return list(map(list, res))
执行用时 :724 ms
内存消耗 :17.2 MB
时间复杂度:, 我们对包含 个元素的列表进行了两层遍历,时间复杂度为 。哈希表查询操作为 ,所以时间复杂度为 。
空间复杂度:, 空间复杂度取决于哈希表中存储的元素数量,该表中存储了 个元素。
解法 3
首先对输入数组排序,然后对数组遍历得到第一个元素,第二、第三个元素采用双指针分别在头尾进行搜索,如果三个元素之和小于目标值,则将头指针向右移动,由于数组已排序,向右移动即可得到值更大的元素;如果三个元素之和大于目标值,则将尾指针向左移动,得到更小的元素,直到两个指针相遇,即可查找到当前循环中所有三数之和等于目标值的元素。这里有两个优化手段,当 i 和 i + 1 相等时,直接跳过 i + 1,避免重复计算;当头指针和右侧元素相等时,或者尾指针和左侧元素相等时,也直接跳过,避免重复计算,这也达到了结果数组去重的目的。
def three_sum(nums):
if len(nums) < 3:
return []
nums.sort()
res = []
for i in range(0, len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
l, r = i + 1, len(nums) - 1
while l < r:
sum = nums[i] + nums[l] + nums[r]
if sum > 0:
r -= 1
elif sum < 0:
l += 1
else:
res.append((nums[i], nums[l], nums[r]))
while l < r and nums[l] == nums[l + 1]:
l += 1
while l < r and nums[r] == nums[r - 1]:
r -= 1
l += 1
r -= 1
return res
执行用时 :1164 ms
内存消耗 :16.6 MB
时间复杂度:, 为了确定第一个元素,我们对包含 个元素的列表进行了一层遍历,为了确定第二、第三个元素,又在第一层遍历中通过双指针再次遍历,时间复杂度为 。哈希表查询操作为 ,所以时间复杂度为 。
空间复杂度:, 用于存放结果的数组不超过 个元素。
参考
https://leetcode-cn.com/problems/3sum/