454 四数相加Ⅱ
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1 。
例如:
输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
输出:
2
解释:
两个元组如下:
(0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
(1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
思路
本题乍眼一看好像和0015.三数之和 (opens new window),0018.四数之和 (opens new window)差不多,其实差很多。
本题是使用哈希法的经典题目,而0015.三数之和 (opens new window),0018.四数之和 (opens new window)并不合适使用哈希法,因为三数之和和四数之和这两道题目使用哈希法在不超时的情况下做到对结果去重是很困难的,很有多细节需要处理。
本题为什么使用哈希?以及如何使用哈希
因为从结果上看,本题四数相加的四个数并不要求去重,而且本题是从四个独立的数组中找数。我们可以统计前两个数组中两两个数相加的值的出现次数,然后从后面两个数组中两两相加的值 看是否存在相反数!然后去获取相应的出现次数——>多少个
使用字典
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
"""
:type nums1: List[int]
:type nums2: List[int]
:type nums3: List[int]
:type nums4: List[int]
:rtype: int
"""
# 本题中是四个独立的数组 且相加为0的四元组可以重复 最终是统计数量 可以考虑字典的键值对 键为两个数之和 值为这个和出现的次数
hashmap = dict() # 定义一个字段
count = 0 # 最终结果
# 前两个数
for i in range(len(nums1)):
for j in range(len(nums2)):
a_b = nums1[i] + nums2[j]
if a_b in hashmap:
hashmap[a_b] += 1 # 前两个数之和 出现次数
else:
hashmap[a_b] = 1 # 不在的话 就是1
# 后两个数
for i in range(len(nums3)):
for j in range(len(nums4)):
c_d = nums3[i] + nums4[j]
if -c_d in hashmap:
count += hashmap[-c_d]
return count
使用deaultdict
defaultdict是python中一个比较好用的工具,通常用于统计次数。
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
"""
:type nums1: List[int]
:type nums2: List[int]
:type nums3: List[int]
:type nums4: List[int]
:rtype: int
"""
# 另外就是使用defaultdict 这很方便
count = 0
hashmap = defaultdict(int) # 初始值都为0
for i in nums1:
for j in nums2:
hashmap[i+j] += 1
for i in nums3:
for j in nums4:
count += hashmap.get(-(i+j), 0) # 获取值 若没有则是0
return count