三数之和

# 给你一个整数数组 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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值