subject
Given a list of n integers , nums , please judge whether there are three elements a, b and c in , so that , a + b + c = 0? Please find all triples with sum 0 and no repetition.
Note: the answer cannot contain duplicate triples.
For example:
Given a list: [- 1, 0, 1, 2, - 1, - 4]
Return result: [- 1, - 1, 2), (- 1, 0, 1)]
Given a list: [1, 2, 4]
Return result: []
Given a list: [- 1, 0, 1, 2, - 1, - 4, 0, 2, 0, 4, - 4, - 2, - 1, 2]
Return result: [(- 4, 0, 4), (- 4, 2, 2), (- 2, 0, 2), (- 1, - 1, 2), (- 1, 0, 1), (0, 0, 0)]
Implementation idea 1
- Refer to previous work Sum of two numbers The method in
- Using two-level loop, the first level loop determines the value of the first number a, the second level loop determines the value of the second number b, and then the third number c = 0 - a - b. We just need to judge whether c appears in the list
- According to the above ideas, it is not difficult for us to implement, but please note that this problem has a requirement: duplicate triples cannot be included, so we need to carry out de duplication, and this detailed process of de duplication is also a major difficulty of this problem
- During de duplication, you can find all qualified triples, put them in a list, and then de duplication. However, such de duplication may not be easy, so we can consider the possible repetition when determining the values of a, b and c
Code implementation 1
def threeSum(nums): res = [] nums.sort() # sort for i in range(len(nums)): if nums[i] > 0: # After sorting, if the first number a is greater than 0, there must be no qualified triples break if i > 0 and nums[i] == nums[i - 1]: # The first number a is de duplicated continue tmp_set = set() for j in range(i + 1, len(nums)): # Considering from J > I + 2, two special cases are allowed: (1) a = b = c = 0; (2) a is negative, b = c and a + b + c = 0 if j > i + 2 and nums[j] == nums[j - 1] and nums[j] == nums[j - 2]: # The second number b is de duplicated continue a, b, c = nums[i], nums[j], 0 - nums[i] - nums[j] if c in tmp_set: res.append((a, b, c)) tmp_set.remove(c) # The third number c is de duplicated else: tmp_set.add(nums[j]) return res
Implementation idea 2
- Using the double pointer method
- First, you need to sort nums from small to large
- The first layer of circulation is also to determine the value of the first number a, and here the possible repetition of a is processed
- Then define two pointers: left and right, which represent the subscripts of the second number b and the third number c respectively. The initial position of left is defined at the next position of a and the initial position of right is defined at the last number of nums
- If a + b + C < 0, because nums is in good order and is less than 0 at this time, it means that the value of b is too small. It is necessary to increase b, that is, move left to the right
- If a + B + c > 0, because nums is in good order and is greater than 0 at this time, it means that the value of c is too large and needs to be reduced, that is, right moves to the left
- If a + b + c = 0, it means that the current triplet meets the conditions, and the triplet is added to the final result
- After adding qualified triples, you also need to consider the possible duplication of b and c to ensure that the final result does not contain duplicate triples
Code implementation 2
def threeSum(nums): res = [] nums.sort() # sort for i in range(len(nums)): if nums[i] > 0: # After sorting, if the first number a is greater than 0, there must be no qualified triples break if i > 0 and nums[i] == nums[i - 1]: # The first number a is de duplicated continue left, right = i + 1, len(nums) - 1 while left < right: a, b, c = nums[i], nums[left], nums[right] if a + b + c < 0: # nums is in good order. If it is less than 0, you need to increase b and move left to the right left += 1 elif a + b + c > 0: # nums is in good order. If it is greater than 0, you need to reduce c and move right to the left right -= 1 else: res.append((a, b, c)) # A is fixed in the outer loop and remains unchanged, so after finding a group of qualified b and c, both left and right need to move left += 1 # left move right right -= 1 # right move left while left < right and nums[left - 1] == nums[left]: # The second number b is de duplicated left += 1 while left < right and nums[right] == nums[right + 1]: # The third number c is de duplicated right -= 1 return res
More Python programming questions are waiting for you to challenge: Python programming problem summary (continuously updated...)