Python programming question 43 -- sum of three numbers

Posted by HughbertD on Sat, 15 Jan 2022 06:32:19 +0100

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...)