leedcode 三数之和

三数之和算法解析
本文深入探讨了求解三数之和问题的两种高效算法。一种是通过字典统计和筛选,另一种是采用排序与双指针技巧,避免重复解并确保结果的准确性。文章详细介绍了每种方法的实现步骤和关键代码。

题解:

首先利用字典计算出每个数字出现的次数。

对于0出现的次数大于等于3时就将[0,0,0]加入到结果列表中

找出负数和正数并且过滤掉重复的数字。

然后遍历负数和正数列表,求0与正数和负数之和的差,看该差是不是在字典中出现过。如果出现则判断该差是不是等于正数或者负数,如果等于则需要保证该差在原来列表中出现的次数大于等于2。如果该差既不等于正数也不等于负数,则将其加入到结果列表。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums_hash = {}
        result = list()
        for num in nums:
            nums_hash[num] = nums_hash.get(num, 0) + 1
        if 0 in nums_hash and nums_hash[0] >= 3:
            result.append([0, 0, 0])

        neg = list(filter(lambda x: x < 0, nums_hash))
        pos = list(filter(lambda x: x >= 0, nums_hash))
        for i in neg:
            for j in pos:
                dif = 0 - i - j
                if dif in nums_hash:
                    if dif in (i, j) and nums_hash[dif] >= 2:
                        result.append([i, j, dif])
                    if dif < i or dif > j:
                        result.append([i, j, dif])
        return result

使用双指针,用来得到三数之中的两个数。因为要保证得到的子数组是bu不重复的,所以想对数组进行排序,从数组的第一个元素i开始,该元素作为三数之中的第一个数,如果该数大于0,则一定不会存在和为0的子数组,否则,利用两个指针,一个指针j指向该元素后面的位置,一个指针k指向排序数组的最后一个位置,然后计算这三个数之和,如果和为0,则加入到结果数组,这时候需要更新j和k,j往后移,如果后移之后元素值和移之前的元素值相同则继续往后移,为了避免出现重复子数组,k往前移,同时也要考虑如果移动之后元素值没变,那继续往前移,同时要保证j小于k,如果和小于0,则j往后移,如果和大于0,则k往前移,需要保证j永远小于k.

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        new_list = nums
        if len(new_list) < 3:
            return []
        new_list.sort()
        res = []
        for i in range(len(new_list) - 2):
            if new_list[i] > 0:
                break
            if i > 0:
                if new_list[i] == new_list[i - 1]:
                    continue
            j = i + 1
            k = len(new_list) - 1
            while j < k:
                sums = new_list[i] + new_list[j] + new_list[k]
                if sums == 0:
                    res.append([new_list[i], new_list[j], new_list[k]])
                    j = j + 1
                    k = k - 1
                    while j < k and nums[j] == nums[j - 1]:
                        j = j + 1
                    while j < k and nums[k] == nums[k + 1]:
                        k = k - 1
                elif sums > 0:
                    k = k - 1
                else:
                    j = j + 1
        return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值