【LeetCode】【15.3sum】(python版)

Description:
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]

思路
前面我们做过Two Sum的问题,这里会想到能不能先固定一个数a,那么就变成了target = - a 的Two Sum的问题,时间复杂度是 O ( n 2 ) O(n^2) O(n2)。实际证明原来使用hash的方法得到结果有重复,并且会TLE。

换种思路,因为不需要记录下标,可以对数组进行排序。假设某个位置的数字为a,需要从后续数组中找到两个数b、c满足b+c=-a。因为此时数组为已排序,因此可以用两指针分别中后续数组的两端往中间找,指针遇到重复的数字直接跳过,就避免了重复结果的出现。时间复杂度仍然是 O ( ( n − 1 ) + ( n − 2 ) + . . . 1 = n ( n − 1 ) / 2 ) = O ( n 2 ) O((n-1)+(n-2)+ ... 1 = n(n-1)/2) = O(n^2) O((n1)+(n2)+...1=n(n1)/2)=O(n2)

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        nums.sort()
        n = len(nums)
        for i in range(n-2):
            # 剪枝,该位置数为正数,那么后面所有数都大于零,三数和不会等于零
            if nums[i] > 0: break
            # 遇见重复值跳过
            if i > 0 and nums[i] == nums[i-1]: continue
            # 搜索两个数从当前循环固定值之后的数组中寻找,避免重复
            low = i + 1
            high = n - 1
            while low < high:
                cursum = nums[low] + nums[high] + nums[i]
                if cursum == 0:
                    res.append([nums[i], nums[low], nums[high]])
                    # 跳过重复数
                    while low < high and nums[low] == nums[low+1]:
                        low = low + 1
                    while low < high and nums[high] == nums[high-1]:
                        high = high - 1
                    high = high - 1
                    low = low + 1
                elif cursum > 0:
                    high = high - 1
                else:
                    low = low + 1
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值