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