好数对的数目-LeetCode
1512. 好数对的数目
🎯 问题描述(来源于LeetCode)
描述:
给你一个整数数组 nums。
如果一组数字 (i, j) 满足 nums[i] == nums[j] 且 i < j,那么它就是一个好数对。
请你返回好数对的数目。
说明:
-
这是一个计数问题。
-
核心逻辑是统计每个数字出现的频率,然后利用组合数学公式计算好数对的数量。
-
对于出现
n次的数字,其好数对的数量为 。 -
示例:
-
示例 1:
1 | 输入:nums = [1,2,3,1,1,3] |
- 示例 2:
1 | 输入:nums = [1,1,1,1] |
💻 解题思路
思路1:哈希表计数 + 组合数学
思路1:代码实现
1 | class Solution: |
思路1:📊 性能分析
- 时间复杂度:
- 其中 是数组
nums的长度。 Counter(nums)需要遍历数组一次,时间复杂度为 。- 遍历
idx.values()的时间复杂度为 ,其中 是不同数字的个数,。 - 总时间复杂度为 。
- 其中 是数组
- 空间复杂度:
- 哈希表
idx在最坏情况下需要存储 个键值对(当所有数字都不同时)。
- 哈希表
思考
-
组合数学原理:
- 对于出现
i次的数字,我们需要从i个位置中选择 2 个位置,且顺序固定(i < j)。 - 这就是组合数 。
- 例如,数字 1 出现 3 次,好数对数量为 。
- 对于出现
-
代码优化:
- 代码中先计算
(i-1) * i,最后再统一除以 2。 - 这是一种常见的优化技巧,可以避免在循环中进行浮点数除法。
- 由于
i(i-1)一定是偶数(两个连续整数中必有一个是偶数),所以最后除以 2 不会丢失精度。
- 代码中先计算
-
替代解法:
- 也可以使用双重循环暴力求解,时间复杂度为 。
- 或者使用哈希表在遍历过程中动态计数,时间复杂度为 ,空间复杂度为 。
-
边界情况:
- 数组长度为 1:没有好数对,返回 0。
- 所有数字都不同:没有好数对,返回 0。
- 所有数字都相同:好数对数量为 。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






