# Solution to problem 18 of leetcode (python analysis)

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

# 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:

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

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

## 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

Topics: Python less