数组唯一数对求和问题:Python代码实现遇阻求助
解决数组唯一数对求和问题
咱们先拆解下你当前代码的问题,再一步步修复它:
你的代码存在的核心问题
- 只收集相邻元素对:你通过
arr[i]和arr[i+1]、arr[i-1]和arr[i]收集数对,这完全忽略了数组中不相邻但和为k的元素组合(比如数组[1,4,3],k=4时,(1,3)这个有效数对就会被漏掉)。 - 错误的去重逻辑:
set(y+l)会把(1,3)和(3,1)判定为不同的元组,但题目要求的是唯一数对,这两个其实属于同一个,应该只算一次。 - 越界错误:当
i=0时,arr[i-1]会取到数组最后一个元素,这会引入完全无关的错误数对。
正确的解决方案
这里提供两种高效的思路,都能满足“找到所有和为k的唯一数对”的需求:
方法1:哈希集合法(时间复杂度O(n))
利用哈希集合记录已遍历的元素,同时用另一个集合存储有效数对(按小值在前、大值在后的方式存储,避免重复):
def pair_sum(arr, k): # 记录已经遍历过的元素 seen = set() # 存储唯一的有效数对 unique_pairs = set() for num in arr: # 计算当前元素需要的补数 complement = k - num if complement in seen: # 按固定顺序存储数对,避免(1,3)和(3,1)被当成不同对 unique_pairs.add( (min(num, complement), max(num, complement)) ) # 将当前元素加入已遍历集合 seen.add(num) # 打印所有有效数对 for pair in unique_pairs: print(pair) # 返回数对数量 return len(unique_pairs)
测试你的示例输入:
pair_sum([1,3,2,2],4)
会输出(1, 3)和(2, 2),返回值为2,完全符合要求。
方法2:排序+双指针法(时间复杂度O(n log n))
先对数组排序,再用左右指针从两端向中间遍历,同时跳过重复元素避免重复数对:
def pair_sum(arr, k): arr.sort() left = 0 right = len(arr) - 1 unique_pairs = set() while left < right: current_sum = arr[left] + arr[right] if current_sum == k: unique_pairs.add( (arr[left], arr[right]) ) # 跳过左侧重复元素 while left < right and arr[left] == arr[left+1]: left += 1 # 跳过右侧重复元素 while left < right and arr[right] == arr[right-1]: right -= 1 # 移动指针继续寻找 left += 1 right -= 1 elif current_sum < k: # 和太小,左指针右移找更大的数 left += 1 else: # 和太大,右指针左移找更小的数 right -= 1 # 打印所有有效数对 for pair in unique_pairs: print(pair) return len(unique_pairs)
同样测试示例输入,也能得到正确结果。
两种方法对比
- 哈希集合法:空间换时间,适合对时间要求高的场景,空间复杂度O(n)。
- 双指针法:不需要额外的哈希集合(除了存储结果),空间复杂度更低,但需要先排序,时间复杂度主要由排序决定(O(n log n))。
内容的提问来源于stack exchange,提问作者Raghav Patnecha
相关产品推荐
相关产品推荐

