前言
“四数之和”的想法
一、题目
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum
二、解法
1.暴力解法
老样子,还是想来for循环,然后结果还是老样子…
class Solution():
def foursum(self,nums,target):
nums.sort()
result = set()
for i in range(len(nums)):
for j in range(i+1,len(nums)):
for x in range(j+1,len(nums)):
for y in range(x+1,len(nums)):
deDup = list(set([i,j,x,y]))
if nums[i] + nums[j] + nums[x] + nums[y] == target and len(deDup) == 4 :
result.add((nums[i] , nums[j] , nums[x] , nums[y]))
return list(result)
# 236/283 over time ...
四个数字之和,把数组内的数字两两相加,可看成是这个数组的两数之和。
但是相加之和的索引需要确定一下,如果从ZUO往右依次两两相加,那么它们是有规律的,所以:
target = 0
nums = [1, 0, -1, 0, -2, 2]
newSet = []
newSet2 = []
result = []
for i in range(len(nums)-1):
for j in range(i+1,len(nums)):
newSet.append(nums[i]+nums[j])
newSet2.append(target-nums[i]-nums[j])
length = len(nums)
count = 1
line = 0
for i in newSet :
if count == length :
line += 1
length -= 1
count = 1
x = count+line
lengthj= len(nums)
countj = 1
linej = 0
for j in newSet2:
if countj == lengthj :
linej += 1
lengthj -= 1
countj = 1
y = countj + linej
if (i == j) and (not(line == linej or line == y or x == y or x == linej)):
a = [nums[line],nums[linej],nums[x],nums[y]]
a.sort()
if a not in result :
result.append(a)
countj += 1
count += 1
print(result)
#最开始就是这么写的,很烂,也超时了,不看也罢
2.指针法
从ZUO往右,循环两个数,然后在剩下的数内首尾放两个指针:
class Solution():
def fourSum(self,nums,target):
if len(nums) < 4 :
return []
nums.sort()
result =set()
for i in range(len(nums)-3):
for j in range(i+1,len(nums)-2):
now = nums[i] + nums[j]
#循环两个数
p = j+1
q = len(nums)-1
while p<q :
if nums[p] + nums[q] + now == target :
result.add((nums[q],nums[p],nums[i],nums[j]))
if nums[p] + nums[q] + now > target :
#确定那个指针移动
q -= 1
else:
p += 1
return list(result)
# Run time: 1128ms Memory consump:14.9MB
3.递归
参考完答案之后写的:
作者:flying_du
链接:https://leetcode-cn.com/problems/4sum/solution/python-wo-jiu-bu-yong-zhi-zhen-fa-zha-di-quan-guo-/
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
output = []
def Search(i, target, oneSolution, notSelected):
if target == 0 and len(oneSolution) == 4:
output.append(oneSolution)
return
#满足条件
elif len(oneSolution) > 4 or i >= len(nums):
return
#不符合答案要求了
if target - nums[i] - (3 - len(oneSolution)) * nums[-1] > 0 or nums[i] in notSelected:
Search(i + 1, target, oneSolution, notSelected)
elif target - (4 - len(oneSolution)) * nums[i] < 0:
return
#剔除没有希望的分支
else:
Search(i + 1, target, oneSolution, notSelected + [nums[i]])
Search(i + 1, target - nums[i], oneSolution + [nums[i]], notSelected)
Search(0, target, [], [])
return output
# Run time: 624ms Memory consump:15.2MB