三数之和-双指针15

python

1.a+b+c=0,自由度为2,所以可以不用三循环,而使用双循环;
2.先给数组从小到大排序,即保证a≤b≤c,从而避免答案出现[a,b,c],[b,c,a]…等重复数组;
3.固定a后,寻找b,c的过程可以利用双指针,b和c分别从前往后和从后往前枚举,从而避免重复查找。

灵感:当出现互为限制的两个变量(即自由度为1)的查找问题时,可以考虑利用双指针。

class Solution:
    def threeSum(self, nums):
        n = len(nums)
        nums.sort() # 为避免重复输出,从小到大对输入数组排序
        ans = list()
        for first in range(n): # a指针,从前往后
            if first > 0 and nums[first] == nums[first-1]: 
            # 避免本次枚举数字的上次一样,从而避免重复
                continue
            third = n-1 # c指针从后往前,从而将三个循环减少为两个
            target = 0 - nums[first]
            for second in range(first+1,n): # b指针,从前往后
                if second > first+1 and nums[second] == nums[second-1]:
                # 避免本次枚举数字的上次一样,从而避免重复
                    continue
                while second < third and nums[second] + nums[third] > target: 
                # b指针要在c指针左侧,避免重复查找
                ''' 由于nums排序为从小到大,故 nums[second] + nums[third] > target 
                可以判断b,c是否符合条件 '''
                    third -= 1
                if second == third: 
                    break # 第二个循环停止
                if nums[second] + nums[third] == target:
                    ans.append([nums[first], nums[second], nums[third]])
        return ans

复杂度分析:

  • 时间复杂度:O(N2),其中 N是数组nums 的长度。
  • 空间复杂度:O(logN),我们忽略存储答案的空间,额外的排序的空间复杂度为O(logN)。然而我们修改了输入的数组nums,在实际情况下不一定允许,因此也可以看成使用了一个额外的数组存储了nums 的副本并进行排序,空间复杂度为 O(N)。

猜你喜欢

转载自blog.csdn.net/VaccyZhu/article/details/113704968