leecode第19天

15、三数之和
# 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,
# 同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
# 注意:答案中不可以包含重复的三元组。
class Solution(object):

    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        hashtable = dict()
        lst=[]
        for i, num in enumerate(nums):
            if target - num in hashtable:
                lst.append(sorted([target-num, num,-target]))          
            hashtable[num] = i
        return lst
    
    def threeSum(self, nums):
        """
        寻找数组中所有和为0的不重复三元组。
        
        :param nums: 输入的整数数组
        :type nums: List[int]
        :return: 返回所有满足条件的三元组列表
        :rtype: List[List[int]]
        """
        # 使用哈希表统计每个数字出现的次数
        hashtable = dict()
        for num in nums:
            if num in hashtable:
                hashtable[num] += 1
            else:
                hashtable[num] = 1
        
        lst = []

        # 检查是否存在三元组 [0, 0, 0]
        if 0 in hashtable and hashtable[0] >= 3:
            lst.append([0, 0, 0])

        # 获取哈希表中的所有键,并排序以优化后续处理
        hashtable_key = list(hashtable.keys())
        hashtable_key.sort()

        # 将数字分为负数和正数两部分
        nums_negative = []
        nums_positive = []
        for num in hashtable_key:
            if num < 0:
                nums_negative.append(num)
            elif num > 0:
                nums_positive.append(num)

        # 检查是否存在三元组 [0, -num, num]
        if 0 in hashtable and hashtable[0] >= 1:
            for num in nums_positive:
                if -num in nums_negative:
                    lst.append(sorted([0, -num, num]))

        # 检查是否存在三元组 [num1, num2, num3],其中 num1 + num2 + num3 = 0
        # 处理正数部分:如果某个正数出现两次或以上,则将其加入临时列表
        if len(nums_positive) != 0:
            lst_temp_positive = []
            for key in nums_positive:
                if hashtable[key] >= 2:
                    lst_temp_positive.append(key)
            nums_positive += lst_temp_positive

        # 处理负数部分:如果某个负数出现两次或以上,则将其加入临时列表
        if len(nums_negative) != 0:
            lst_temp_negative = []
            for key in nums_negative:
                if hashtable[key] >= 2:
                    lst_temp_negative.append(key)
            nums_negative += lst_temp_negative

        # 遍历负数列表,调用 twoSum 方法寻找与当前负数相加为零的正数对
        for num in nums_negative:
            lst_temp = self.twoSum(nums_positive, -num)
            lst += lst_temp

        # 遍历正数列表,调用 twoSum 方法寻找与当前正数相加为零的负数对
        for num in nums_positive:
            lst_temp = self.twoSum(nums_negative, -num)
            lst += lst_temp

        # 去重:将结果列表中的三元组转换为集合后再转回列表
        lst = list(map(list, set(map(tuple, lst))))
        return lst
Yes
No
开始
构建哈希表
是否有至少三个0?
添加 0, 0, 0
分类负数和正数
处理 0, -num, num
处理重复数字
遍历负数调用 twoSum
遍历正数调用 twoSum
去重结果
返回结果

问题分析与优化建议

1. 潜在问题
  • 异常处理不足:代码中没有对输入参数 nums 进行类型检查,如果传入的不是列表或包含非整数元素,可能会引发运行时错误。
  • 边界条件未充分考虑:当输入数组为空或长度小于3时,代码虽然不会报错,但可以更明确地处理这种情况。
  • 去重逻辑效率较低:当前使用 set(map(tuple, lst)) 去重的方式虽然有效,但会增加额外的时间和空间开销。
2. 优化方向
  • 输入验证:在函数开头添加对输入参数的类型和内容检查,确保输入为整数列表。
  • 边界条件优化:明确处理输入数组为空或长度小于3的情况。
  • twoSum 方法实现:提供一个高效的实现,避免重复计算。
  • 去重逻辑优化:通过排序和跳过重复值的方式减少不必要的计算,同时避免使用集合去重。
class Solution(object):

    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        seen = set()  # 用于存储已经访问过的数字
        pairs = []
        for num in nums:
            complement = target - num  # 计算当前数字的补数
            if complement in seen:  # 检查补数是否已经在集合中
                pairs.append(sorted([complement, num]))  # 如果存在,添加到结果中
            seen.add(num)  # 将当前数字添加到集合中
        return pairs

    def threeSum(self, nums):
        """
        寻找数组中所有和为0的不重复三元组。
        
        :param nums: 输入的整数数组
        :type nums: List[int]
        :return: 返回所有满足条件的三元组列表
        :rtype: List[List[int]]
        """
        # 输入验证
        if not isinstance(nums, list) or not all(isinstance(x, int) for x in nums):
            raise ValueError("输入必须是整数列表")
        
        # 边界条件处理
        if len(nums) < 3:
            return []

        # 对数组进行排序
        nums.sort()

        result = []

        # 遍历数组,寻找三元组
        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:
                total = nums[i] + nums[left] + nums[right]
                if total == 0:
                    result.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 total < 0:
                    left += 1
                else:
                    right -= 1

        return result

优化点总结

  1. twoSum 方法优化:使用双指针方法替代哈希表方法,确保正确处理重复元素。
  2. 去重逻辑优化:通过排序和跳过重复值的方式减少不必要的计算,避免使用集合去重。
  3. 边界条件处理:确保代码在处理边界条件时逻辑正确。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值