面试题 16.24-数对和-LeetCode
面试题 16.24. 数对和
🎯 问题描述(来源于LeetCode)
描述:
设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。
给定一个整数数组 nums 和一个目标值 target,请返回所有满足条件的数对。
说明:
-
这是一个哈希表计数结合贪心算法的问题。
-
核心逻辑是:对于每个数字
num,查找其互补数target - num是否已经出现过且未被使用。 -
如果存在,则组成一个数对,并减少互补数的可用数量。
-
如果不存在,则将当前数字加入哈希表,等待后续的互补数。
-
示例:
-
示例 1:
1 | 输入:nums = [5,6,5], target = 11 |
- 示例 2:
1 | 输入:nums = [5,6,5,6], target = 11 |
💻 解题思路
思路1:哈希表 + 贪心匹配
思路1:代码实现
1 | class Solution: |
思路1:📊 性能分析
- 时间复杂度:
- 其中 是数组
nums的长度。 - 我们只遍历数组一次,每次哈希表操作(查找、插入、更新)的平均时间复杂度都是 。
- 总时间复杂度为 。
- 其中 是数组
- 空间复杂度:
- 哈希表
count在最坏情况下需要存储 个键值对。 - 结果列表
ans在最坏情况下存储 个数对。
- 哈希表
思考
-
贪心策略:
- 我们想要找出所有可能的数对,因此每当遇到一个数字
num,如果它的互补数target - num已经出现过(且未被完全配对),我们就立即进行配对。 - 这种“立即配对”的策略是贪心的,因为它不会错过任何可能的配对机会。
- 我们想要找出所有可能的数对,因此每当遇到一个数字
-
哈希表的作用:
- 哈希表用于记录尚未配对的数字及其出现次数。
- 键是数字本身,值是该数字的剩余可用数量。
-
逻辑流程:
- 遍历每个数字
num。 - 计算其互补数
complement = target - num。 - 检查
complement是否在哈希表中且数量大于 0:- 是:说明可以配对。将
[complement, num]加入结果列表,complement的计数减 1(表示一个complement已被使用)。 - 否:说明当前无法配对。将
num的计数加 1(表示这个num等待后续的互补数)。
- 是:说明可以配对。将
- 遍历每个数字
-
处理重复数字:
- 代码通过
count[complement] > 0和count[complement] -= 1正确处理了重复数字的情况。 - 例如,
nums = [5,5,6,6], target = 11:- 第一个 5:
complement = 6,不在哈希表中,count[5] = 1。 - 第二个 5:
complement = 6,不在哈希表中,count[5] = 2。 - 第一个 6:
complement = 5,在哈希表中且count[5] = 2 > 0,配对成功,ans = [[5,6]],count[5] = 1。 - 第二个 6:
complement = 5,在哈希表中且count[5] = 1 > 0,配对成功,ans = [[5,6],[5,6]],count[5] = 0。
- 第一个 5:
- 最终结果为
[[5,6],[5,6]],正确。
- 代码通过
-
边界情况:
- 数组长度为 1:无法配对,返回空列表。
- 所有数字都相同且
2 * num != target:无法配对,返回空列表。 - 所有数字都相同且
2 * num == target:可以配对N // 2对。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






