题目链接
题目描述
给你一个下标从 0
开始的整数数组 nums
。如果 i < j
且 j - i != nums[j] - nums[i]
,那么我们称 (i, j)
是一个 坏数对 。
请你返回 nums
中 坏数对 的总数目。
示例 1:
输入:nums = [4,1,3,3]
输出:5
解释:数对 (0, 1) 是坏数对,因为 1 - 0 != 1 - 4 。
数对 (0, 2) 是坏数对,因为 2 - 0 != 3 - 4, 2 != -1 。
数对 (0, 3) 是坏数对,因为 3 - 0 != 3 - 4, 3 != -1 。
数对 (1, 2) 是坏数对,因为 2 - 1 != 3 - 1, 1 != 2 。
数对 (2, 3) 是坏数对,因为 3 - 2 != 3 - 3, 1 != 0 。
总共有 5 个坏数对,所以我们返回 5 。
示例 2:
输入:nums = [1,2,3,4,5]
输出:0
解释:没有坏数对。
提示:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
解题思路
- 数对的总数为
len * (len - 1) / 2
- 因为
j-i != nums[j] - nums[i]
,也就是nums[i] - i != nums[j] - j
- 那么只要找出
nums[i] - i == nums[j] - j
的数量,再用总数减去即可得到答案 - 因此采用哈希表将
nums[i] - i
进行计数,具有相同key值得,可以构成好数对
AC代码
class Solution {
public long countBadPairs(int[] nums) {
int len = nums.length;
long ans = (long) len * (len - 1) / 2;
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < len; i++) {
int key = nums[i] - i;
int value = map.getOrDefault(key, 0);
// 每次都减去好数对组成得个数,加1是说明这个键已经出现过对应值了
ans -= value;
map.put(key, value + 1);
}
return ans;
}
}