🧾题目描述
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
**注意:**答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
💡解题思路:排序 + 双指针
这道题是经典的"排序 + 双指针"套路。
🔍具体步骤如下:
-
排序数组,便于去重与双指针操作。
-
遍历数组,固定第一个数
nums[i]。-
若
nums[i] > 0,后续无需判断,直接 break(因为数组已排序,三数和一定 > 0)。 -
如果当前数等于前一个数
nums[i] == nums[i-1],则跳过,防止重复三元组。
-
-
双指针 :从
i+1到len(nums)-1分别设置left和right,寻找两个数使得nums[i] + nums[left] + nums[right] == 0。 -
如果找到满足条件的三元组:
- 记录后,跳过相同元素(避免重复组合)。
-
如果三数之和小于 0,左指针右移;大于 0,右指针左移。
✅代码实现(Python)
python
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# 排序 + 双指针
nums.sort()
res = []
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, len(nums) - 1
while left < right:
tot = nums[i] + nums[left] + nums[right]
if tot == 0:
res.append([nums[i], nums[left], nums[right]])
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
left += 1
right -= 1
elif tot < 0:
left += 1
else:
right -= 1
return res
⏱️复杂度分析
-
时间复杂度:O(n²)
排序是 O(nlogn),双指针搜索是 O(n²)。
-
空间复杂度:O(1)(不包含结果的存储)
🧠总结
-
本题是 LeetCode 高频面试题,考察排序、去重处理与双指针技巧。
-
处理重复三元组是关键难点,务必要掌握如何在排序后的数组中跳过重复值。
-
延伸题型:四数之和(4Sum) 、三数之和靠近目标(3Sum Closest)