题目

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 _a + b + c = _0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。

示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4]

满足要求的三元组集合为:

  1. [
  2. [-1, 0, 1],
  3. [-1, -1, 2]
  4. ]

方案一

  1. class Solution:
  2. def threeSum(self, nums: List[int]) -> List[List[int]]:
  3. # 双指针
  4. if len(nums) < 2:
  5. return []
  6. nums.sort()
  7. i, j, k = 1, len(nums) - 1, 0
  8. res = []
  9. # 固定一个指针 k
  10. while k < len(nums):
  11. if nums[k] > 0: # 最小的数大于 0
  12. break
  13. # i, j 从两端往中间步进
  14. while i < j:
  15. count = nums[k] + nums[i] + nums[j]
  16. if count == 0:
  17. res.append([nums[k], nums[i], nums[j]])
  18. i += 1
  19. j -= 1
  20. while i < j:
  21. if nums[i] == nums[i - 1]: # 连续相同
  22. i += 1
  23. else:
  24. break
  25. while i < j:
  26. if nums[j] == nums[j + 1]: # 连续相同
  27. j -= 1
  28. else:
  29. break
  30. elif count < 0:
  31. i += 1
  32. while i < j:
  33. if nums[i] == nums[i - 1]: # 连续相同
  34. i += 1
  35. else:
  36. break
  37. else:
  38. j -= 1
  39. while i < j:
  40. if nums[j] == nums[j + 1]: # 连续相同
  41. j -= 1
  42. else:
  43. break
  44. k += 1
  45. while k < len(nums):
  46. if nums[k] == nums[k - 1]: # 连续相同
  47. k += 1
  48. else:
  49. break
  50. i = k + 1
  51. j = len(nums) - 1
  52. return res

优化代码结构

  1. class Solution:
  2. def threeSum(self, nums: List[int]) -> List[List[int]]:
  3. # 双指针
  4. if len(nums) < 2:
  5. return []
  6. nums.sort()
  7. i, j, k = 1, len(nums) - 1, 0
  8. res = []
  9. # 固定一个指针 k
  10. while k < len(nums):
  11. if nums[k] > 0: # 最小的数大于 0
  12. break
  13. while i < j:
  14. count = nums[k] + nums[i] + nums[j]
  15. if count == 0:
  16. res.append([nums[k], nums[i], nums[j]])
  17. i += 1
  18. j -= 1
  19. # 跳过相同元素
  20. while i < j and nums[i] == nums[i - 1]: i += 1
  21. while i < j and nums[j] == nums[j + 1]: j -= 1
  22. elif count < 0:
  23. i += 1
  24. while i < j and nums[i] == nums[i - 1]: i += 1
  25. else:
  26. j -= 1
  27. while i < j and nums[j] == nums[j + 1]: j -= 1
  28. k += 1
  29. while k < len(nums) - 1 and nums[k] == nums[k - 1]: k += 1
  30. # 重置 i, j 指针
  31. i = k + 1
  32. j = len(nums) - 1
  33. return res
  1. class Solution:
  2. def twoSum(self, nums, target, l, r):
  3. """
  4. :type nums: List[int]
  5. :type target: int
  6. :rtype: List[int]
  7. """
  8. n = len(nums[l: r+1])
  9. if n < 2:
  10. return set()
  11. start = nums[l - 1]
  12. dict1 = dict()
  13. ret = set()
  14. for i in range(l, r+1):
  15. other = target - nums[i]
  16. if other in dict1:
  17. ret.add((start, other, nums[i]))
  18. dict1[nums[i]] = i
  19. return ret
  20. def threeSum(self, nums):
  21. """
  22. :type nums: List[int]
  23. :type target: int
  24. :rtype: List[int]
  25. """
  26. n = len(nums)
  27. if n < 3:
  28. return []
  29. nums.sort()
  30. ret = set()
  31. for i in range(n):
  32. # nums[i] 为正数,表示后面不可能有两数之后为负
  33. if nums[i] > 0:
  34. break
  35. if (i >= 1 and nums[i] == nums[i-1]):
  36. continue
  37. ll = self.twoSum(nums, -nums[i], i+1, n-1)
  38. if ll == set():
  39. continue
  40. ret = ret | ll
  41. return list(ret)