输入一个非空数组和一个目标值targetsum。如果数组中有四个数的和等于目标值,则返回这四个数的左右可能的组合,否则返回一个空数组。
样例输入:
[7, 6, 4, -1, 1, 2]
targetsum = 16
样例输出:
[[7, 6, 4, -1], [7, 6, 1, 2]]
解决这道题的虽简单的方法是暴力搜索,但是时间复杂度将达到惊人的 O ( n 4 ) O(n^4) O(n4)。
实际上有更好的办法。
先设定一个哈希表,也就是python中的字典,用来存储 {和-两个数} 这样的组合,这样在遍历所有其他两种数字的组合的同时,
将targetsum减去当前正在遍历的两个数的和得到一个difference, 查询这个difference是否在哈希表中存在,如果存在,则将当前的这两个遍历的数字和哈西表中difference对应的vualue中存在的二值数组拼接起来,组成一个四个值的数组,记录在需要返回的list中。
Solution:
test_array = [7, 6, 4, -1, 1, 2]
target_sum = 16
def fourNumberSum(array, targetSum):
#建立空的字典(也就是哈希表)储存所有的{和:[[值a,值b],[值x],[值z]]}对子
all_pair_dic = {}
quadruplet = []
#遍历每一个元素,在计算对子的同时寻找targetSum减去inner和outer的和的差在不在对子清单里面
for outer in range(1,len(array)-1):
for inner in range(outer+1,len(array)):
current_sum = array[outer]+array[inner]
current_difference = targetSum - current_sum
#如果在清单里面,就把清单的对子加inner和outer指向的数字合成四个数字记录下来
if current_difference in all_pair_dic:
# print(all_pair_dic)
for each_pair in all_pair_dic[current_difference]:
quadruplet.append(each_pair + [array[outer],array[inner]])
#寻找二值对子,把没见过的连同他们的和作为key,放到哈希表中
for _ in range(0,outer):
current_sum = array[outer] + array[_]
if current_sum not in all_pair_dic:
all_pair_dic[current_sum] = [[array[_], array[outer]]]
else:
all_pair_dic[current_sum].append([array[_],array[outer]])
return quadruplet
print(fourNumberSum(array = test_array,targetSum = target_sum))
#Time: O(n^2)
#Space: O(n^2)
Average: Time:$ O(n^2)$|Space: O ( n 2 ) O(n^2) O(n2)
Worst: Time: O ( n 3 ) O(n^3) O(n3)| Space: O ( n 2 ) O(n^2) O(n2)