带负数与重复元素的二维数组子集和变体问题优化求解
嘿,这个问题我之前也踩过坑!直接暴力枚举确实完全顶不住,尤其是n稍微大一点的时候,程序根本跑不完。咱们可以用分治+哈希表的思路把时间复杂度直接降到O(N²),这是这类问题最经典的优化方向,我给你拆解下具体怎么操作:
核心优化思路:分治(Divide and Conquer)
把四列拆成两组(前两列一组、后两列一组),分别计算两组的所有可能和,再通过哈希表快速匹配符合目标的组合。
第一步:统计前两列的所有和及其出现次数
- 遍历第一列的每个元素
a,再遍历第二列的每个元素b,计算s1 = a + b - 用一个哈希表(比如Python里的
collections.defaultdict,或者Java的HashMap)记录每个s1出现的次数——键是和的值,值是该和对应的组合数量
第二步:遍历后两列的和,匹配目标值
- 遍历第三列的每个元素
c,再遍历第四列的每个元素d,计算s2 = c + d - 我们需要找的是
target - s2这个值在第一步的哈希表里出现的次数,把这些次数累加起来,就是符合条件的总组合数
为什么这个思路效率高?
- 前两列的组合数是NN,后两列也是NN,总时间复杂度是O(N²),对比暴力解法的O(N⁴),差距天差地别:比如当N=1000时,暴力要执行1e12次操作,优化后只需要2e6次
- 哈希表的查找操作是O(1)级别的,匹配过程几乎不耗时
额外注意事项
- 负数完全不影响:哈希表可以正常存储负数作为键
- 重复元素也无需特殊处理:因为我们统计的是每个和的出现次数,重复元素会自然累加对应的组合数
举个简单的例子直观感受下:
假设数组是:
[1, 2] [3, 4] [5, 6] [7, 8]
目标和为20
- 前两列的和:
1+3=4、1+4=5、2+3=5、2+4=6,哈希表最终是{4:1, 5:2, 6:1} - 后两列的和:
5+7=12、5+8=13、6+7=13、6+8=14 - 计算
20 - s2:8(无匹配)、7(无匹配)、7(无匹配)、6(匹配到1次),总组合数就是1,对应组合2+4+6+8=20,完全正确
如果担心哈希表的空间问题也不用慌:当N=1e3时,最多只会有1e6个不同的和,现代内存完全能轻松承载。
内容的提问来源于stack exchange,提问作者Harry F
相关产品推荐
相关产品推荐

