三数之和(15)

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        if not nums or len(nums)<3:
            return []

        res = []
        n = len(nums)
        for i in range(n):
            if nums[i]>0:
                return res
            if (i>0 and nums[i]==nums[i-1]):
                continue

            L=i+1
            R=n-1
            while L<R:
                if nums[i]+nums[L]+nums[R]==0:
                    res.append([nums[i],nums[L],nums[R]])
                    while L<R and nums[L]==nums[L+1]:
                        L+=1
                    while L<R and nums[R]==nums[R-1]:
                        R-=1
                    L+=1
                    R-=1
                elif nums[i]+nums[L]+nums[R]<0:
                    L+=1
                else:
                    R-=1
        return res

法二:

class Solution:
  def threeSum(self, nums: List[int]) -> List[List[int]]:
    if not nums: return []

    # 先排序,关键!
    nums.sort()
    ans = set()
    N, target = 3, 0
    self._find_sum(nums, 0, N, target, [], ans)
    return list(ans)

  def _find_sum(self, nums, start, N, target, path, ans):
    # terminator
    if len(nums) < N or N < 2: return
    # process
    if N == 2:
      # 两数求和
      d = set()
      for j in range(start, len(nums)):
      if target - nums[j] in d:
        ans.add(tuple(path + [target - nums[j], nums[j]]))
      else:
        d.add(nums[j])
    else:
      for i in range(start, len(nums)):
        # 剪枝1: target比剩余数字能组成的最小值还要小 或 比能组成的最大值还要大,就可以停止循环了
        if target < nums[i] * N or target > nums[-1] * N: break
        # 剪枝2: 去重
        if i > start and nums[i] == nums[i - 1]: continue
        # drill down
        self._find_sum(nums, i + 1, N - 1, target - nums[i], path + [nums[i]], ans)
    return

 

 

posted on 2020-08-11 17:32  不要挡着我晒太阳  阅读(70)  评论(0编辑  收藏  举报

导航