15.3Sum(python)

1.Description:

Given an array nums of n integers, are there elements abc 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]
]

2.Ideas:

这道题需要从一个列表中选出所有满足和为0的三元组,且要求去重,最简单的思路就是暴力的3层循环,这样肯定会超时。我们可以简单的进行分析,三个数的和为零,可以先确定一个数,然后再确定另外两个数,使另外两个数的和为第一个确定数的相反数,这样就可以将O(n^3)转为O(n^2)。我们可以让第一个确定的数为一个不大于0的数,而且,因为最快的排序算法的时间复杂度是O(nlogn)<O(n^2),因此,我们可以先为列表排序。然后,从第一个开始遍历,最远遍历到倒数第三个,最近遍历到一个正数为止(因为3个大于0的数,和一定也大于0),这个遍历为最外层遍历,注意,这个遍历需要进行去重,即:如果当前位置的值等于下一个位置的值,那么就继续推进。内层循环用来确定另外两个值,循环方式可以选择从首位向中间推进的方式:当首位值相加等于第一个数的相反数时,需要在结果列表中进行添加,然后首尾分别进行推进,并且注意去重;如果首尾值相加小于第一个数的相反数,那么左边向右推进,同时注意去重;如果首尾值相加大于第一个数的相反数,那么右边向左推进,同时注意去重。最终就可以得到全部的结果。

3.Code:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        L = []
        nums.sort()
        length = len(nums)
        if(length<3):
            return L
        for i in range(length-2):
            if(nums[i]>0):#三个大于0的数之和不会是0
                break
            if(i>0 and nums[i]==nums[i-1]):#去掉重复的情况
                continue
            target = -nums[i]
            left = i+1
            right = length-1
            while left < right:
                if(nums[left]+nums[right]==target):
                    temp = []
                    temp.append(nums[i])
                    temp.append(nums[left])
                    temp.append(nums[right])
                    L.append(temp)
                    left+=1
                    right-=1
                    while left<right and nums[left]==nums[left-1]:left+=1
                    while left<right and nums[right]==nums[right+1]:right-=1
                elif(nums[left] + nums[right] <target):
                    while left < right:
                        left += 1
                        if nums[left] > nums[left - 1]: break
                else:
                    while left < right:
                        right -= 1
                        if nums[right] < nums[right + 1]: break
        return L

4.Result:

发布了28 篇原创文章 · 获赞 6 · 访问量 2468

猜你喜欢

转载自blog.csdn.net/Kobe_1314/article/details/92996844