Solution to problem 18 of leetcode (python analysis)

Posted by freephoneid on Sat, 18 Jan 2020 18:46:15 +0100

leetcode brush inscription -- > 18 problem solving method (python analysis)

Definition of title

Given a n array of N integers nums a n d a target value target, judge whether there are four elements a, b, c and D in nums, so that the value of a + b + c + d is equal to target? Find all quads that meet the conditions and are not repeated.

Be careful:

The answer cannot contain duplicate quads.

Example:

Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.

The set of quads that meet the requirements is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

Source: LeetCode
Links: 18 questions of leetcode.

Solving problems

Four methods are used this time. There are more methods on leetcode. I can only say that it's really awesome and smart.

1. Use dichotomy

2. Optimization by dichotomy

3. Use recursive thinking

4. Continue to optimize the dichotomy

===================================================

Realization

// An highlighted block

class Solution:
    def fourSum(self, nums, target):
        '''
        //Change from the sum of three numbers to the sum of four numbers using dichotomy
        '''
        nums.sort()
        res = []
        length = len(nums)
        for i in range(length):
            for j in range(i+1,length):
                l = j+1
                r = length-1

                while l<r:
                    end = target-nums[i]-nums[j]-nums[r]-nums[l]
                    if end == 0:
                        res.append([nums[i],nums[j],nums[l],nums[r]])
                        l+=1
                        r-=1
                        while l < r and nums[l] == nums[l - 1]:  # De duplication if the number on the left is the same
                            l += 1
                        while r > l and nums[r] == nums[r + 1]:  # De duplication if the number on the right is the same
                            r -= 1
                    elif end > 0:
                        l += 1
                    else:
                        r -= 1
        return list(set(map(tuple, res)))


    def fourSum_1(self, nums, target) :
        '''
        //The first kind of optimization
        '''
        nums.sort()
        length = len(nums)
        ans = []
        for i in range(length):
            for j in range(i + 1, length):
                l, r, t = j + 1, length - 1, target - nums[i] - nums[j]
                while l < r:
                    while l < r and t > nums[l] + nums[r]: l += 1
                    while l < r and t < nums[l] + nums[r]: r -= 1
                    if l < r and nums[l] + nums[r] == t:
                        ans.append([nums[i], nums[j], nums[l], nums[r]])
                    l += 1
        return list(set(map(tuple, ans)))



    def fourSum_2(self, nums, target):
        '''

        //It's OK to use this method when the sum of three is over, but the sum of four is over
        '''
        import itertools

        ts, bs = [i for i in set(list(itertools.combinations(nums, 4))) if
                  sum(i) == target], {}  # Find out all combinations and then set to determine the addition ts equal to 0
        for i in ts:
            '''
            >>frozenset((-1, 0, -1))
            frozenset({-1, 0})
            //Input [- 1, 0, 1, 2, - 1, - 4]
            //Output {frozenset({2, -1}): (-1, 2, -1), frozenset({0, 1, -1}): (-1, 0, 1)}
            '''
            bs.update({frozenset(i): i}) if frozenset(i) not in list(bs.keys()) else 0  # Store the key of the dictionary as a frozen

        return list(bs.values())

    def fourSum_3(self, nums, target):
        '''
        //Recursive thinking
        //In fact, if you change the value of flag, it will become the sum of n numbers

        '''
        def Sum(inp, target, flag):
            result = []

            if flag == 1:
                if target in inp:
                    return [[target]]
                else:
                    return
            else:
                for i in range(len(inp)):
                    if i != 0 and inp[i] == inp[i - 1]:
                        continue
                    temp = Sum(inp[i + 1:], target - inp[i], flag - 1)
                    if temp:
                        for item in temp:
                            item.append(inp[i])
                            result.append(item)
            return result

        nums.sort()
        return Sum(nums, target, 4)

    def fourSum_4(self, nums: List[int], target: int) -> List[List[int]]:
        '''
        //The fastest algorithm kills all the people in front of it and defeats 99% of python users
        '''
        result = []
        if not nums or len(nums) < 4:
            return []
        nums.sort()
        # Array length
        length = len(nums)
        # Define four pointers k, i, J, H k to traverse from 0, i to traverse from k+1, leaving J and h, j to traverse i+1, h to array maximum
        for k in range(length - 3):
            # Ignore when the value of k is equal to the previous value
            if k > 0 and nums[k] == nums[k - 1]:
                continue
            # Get the current minimum value. If the minimum value is larger than the target value, it means that the larger and larger value is useless
            min1 = nums[k] + nums[k + 1] + nums[k + 2] + nums[k + 3]
            if min1 > target:
                break
            # Get the current maximum value. If the maximum value is smaller than the target value, it means that the later smaller value is useless. Ignore
            max1 = nums[k] + nums[length - 1] + nums[length - 2] + nums[length - 3]
            if max1 < target:
                continue
            for i in range(k + 1, length - 2):
                if i > k + 1 and nums[i] == nums[i - 1]:
                    continue
                j = i + 1
                h = length - 1
                min2 = nums[k] + nums[i] + nums[j] + nums[j + 1]
                if min2 > target:
                    continue
                max2 = nums[k] + nums[i] + nums[h] + nums[h - 1]
                if max2 < target:
                    continue
                # Start the performance of J pointer and H pointer, calculate the current sum, if equal to the target value, j + + and de duplicate, h -- and de duplicate, when the current sum is greater than the target value, h --, when the current sum is less than the target value, j++
                while j < h:
                    curr = nums[k] + nums[i] + nums[j] + nums[h]
                    if curr == target:
                        result.append([nums[k], nums[i], nums[j], nums[h]])
                        j += 1
                        while j < h and nums[j] == nums[j - 1]:
                            j += 1
                        h -= 1
                        while j < h and i < h and nums[h] == nums[h + 1]:
                            h -= 1
                    elif curr > target:
                        h -= 1
                    elif curr < target:
                        j += 1

        return result


print(Solution().fourSum_3([1, 0, -1, 0, -2, 2],0))
Published 8 original articles, won praise 0, visited 130
Private letter follow

Topics: Python less