# 给你一个整数数组 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 = [-1,0,1,2,-1,-4] 为例:
# 排序后:[-4, -1, -1, 0, 1, 2];
# first=0(a=-4),target=4,找 b + c=4:
# second=1(b=-1),third=5(c=2)→ -1+2=1 <4,无操作;
# 遍历 second 直到无符合条件的 c;
# first=1(a=-1),target=1,找 b + c=1:
# second=2(b=-1,和前一个 b 重复,跳过);
# second=3(b=0),third=5(c=2)→ 0+2=2>1,third 左移到 4(c=1);
# 0+1=1 == target,加入三元组 [-1,0,1];
# second=4(b=1),third=4(重合,退出);
# 最终结果:[[-1,-1,2],[-1,0,1]],符合预期。
from typing import List
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
# 方便跳过重复元素(相同元素相邻,只需判断当前元素是否和前一个一致);
# 双指针可通过「大小比较」向中间移动,快速缩小搜索范围。
nums.sort()
# 存储最终结果(不重复的三元组)
ans = list()
# 枚举a(对应 first 指针,三元组第一个数)
for first in range(n):
# 需要和上一次枚举的数不相同
# 去重:如果当前 a 和前一个 a 相同,跳过(避免重复三元组)
if first > 0 and nums[first] == nums[first - 1]:
continue
# c 的指针初始指向数组最右端(三元组第三个数)
third = n - 1
# 转化目标:b + c = -a(等价于 a + b + c = 0)
target = -nums[first]
# 枚举 b(对应 second 指针,三元组第二个数),从 first+1 开始(避免和 a 重复)
for second in range(first + 1, n):
# 去重:当前 b 和前一个 b 相同,跳过(同一 a 下的重复 b)
if second > first + 1 and nums[second] == nums[second - 1]:
continue
# 移动 third 指针:保证 b < c,且 b + c ≤ target
while second < third and nums[second] + nums[third] > target:
third -= 1
# 指针重合:后续 b 增大,b + c 只会更大,不可能等于 target,直接退出
if second == third:
break
# 找到符合条件的三元组:b + c = target → a + b + c = 0
if nums[second] + nums[third] == target:
ans.append([nums[first], nums[second], nums[third]])
return ans
if __name__ == "__main__":
solution = Solution()
nums = [-1,0,1,2,-1,-4]
res = solution.threeSum(nums)
print(res)
三数之和
于 2025-12-09 13:13:32 首次发布
2280

被折叠的 条评论
为什么被折叠?



