统计坏数对的数目-LeetCode
2364. 统计坏数对数目
🎯 问题描述(来源于LeetCode)
描述:
给你一个下标从 0 开始的整数数组 nums。
如果 i < j 且 j - i != nums[j] - nums[i],那么我们称 (i, j) 是一个坏数对。
请你返回 nums 中坏数对的总数目。
说明:
-
这是一个哈希表计数结合补集思想的问题。
-
直接思考:判断
j - i != nums[j] - nums[i]比较麻烦。 -
转换思考:
- 不等式
j - i != nums[j] - nums[i]等价于nums[i] - i != nums[j] - j。 - 反之,好数对满足
j - i == nums[j] - nums[i],即nums[i] - i == nums[j] - j。
- 不等式
-
策略:
- 计算所有可能的数对总数 。
- 计算满足
nums[i] - i == nums[j] - j的好数对数量 。 - 答案即为 。
-
示例:
-
示例 1:
1 | 输入:nums = [4,1,3,3] |
💻 解题思路
思路1:补集思想 + 哈希表
思路1:代码实现
1 | class Solution: |
思路1:📊 性能分析
- 时间复杂度:
- 其中 是数组
nums的长度。 - 遍历数组一次进行哈希表统计,耗时 。
- 计算总数对耗时 。
- 总时间复杂度为 。
- 其中 是数组
- 空间复杂度:
- 哈希表
count在最坏情况下存储 个不同的键值。
- 哈希表
思考
-
数学变换(核心):
- 题目给出的条件是
j - i != nums[j] - nums[i]。 - 直接统计“不等于”的情况很难,因为每个不等的数对差值都不一样。
- 但是统计“等于”的情况(好数对)很容易:
nums[j] - j == nums[i] - i。 - 我们将每个元素的
index - value作为特征值。只要特征值相同,就是好数对。
- 题目给出的条件是
-
补集思想:
- 全集 是所有可能的 组合,其中 。总数为 。
- 子集 是好数对。
- 目标集合 是坏数对。
- 。
-
累加计数法:
- 在遍历过程中,
good_pairs += count[key]利用了累加技巧。 - 假设某个
key之前出现了 次,当前是第 次。 - 当前元素可以和之前的 个元素分别组成好数对,所以增加 个。
- 在遍历过程中,
-
边界情况:
- 数组长度为 1:总数对为 0,好数对为 0,结果为 0。
- 所有元素都相同:例如
[2,2,2]。- i=0, key=-2
- i=1, key=-1
- i=2, key=0
- 所有 key 不同,好数对为 0,坏数对 = 总数对。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






