题目
标题和出处
标题:数组中的 k-diff 数对
难度
4 级
题目描述
要求
给定一个整数数组 nums \texttt{nums} nums 和一个整数 k \texttt{k} k,返回不同的 k \texttt{k} k-diff 数对的数目。
一个 k \texttt{k} k-diff 数对为一个整数对 (nums[i], nums[j]) \texttt{(nums[i], nums[j])} (nums[i], nums[j]),并满足下述条件:
- 0 ≤ i, j < nums.length \texttt{0} \le \texttt{i, j} < \texttt{nums.length} 0≤i, j<nums.length
- nums[i] ≤ nums[j] \texttt{nums[i]} \le \texttt{nums[j]} nums[i]≤nums[j]
- |nums[i] - nums[j]| = k \texttt{|nums[i] - nums[j]|} = \texttt{k} |nums[i] - nums[j]|=k
注意, |val| \texttt{|val|} |val| 表示 val \texttt{val} val 的绝对值。
示例
示例 1:
输入:
nums
=
[3,
1,
4,
1,
5],
k
=
2
\texttt{nums = [3, 1, 4, 1, 5], k = 2}
nums = [3, 1, 4, 1, 5], k = 2
输出:
2
\texttt{2}
2
解释:数组中有两个
2
\texttt{2}
2-diff 数对,
(1,
3)
\texttt{(1, 3)}
(1, 3) 和
(3,
5)
\texttt{(3, 5)}
(3, 5)。
尽管数组中有两个
1
\texttt{1}
1,但我们只应返回不同的数对的数量。
示例 2:
输入:
nums
=
[1,
2,
3,
4,
5],
k
=
1
\texttt{nums = [1, 2, 3, 4, 5], k = 1}
nums = [1, 2, 3, 4, 5], k = 1
输出:
4
\texttt{4}
4
解释:数组中有四个
1
\texttt{1}
1-diff 数对,
(1,
2)
\texttt{(1, 2)}
(1, 2),
(2,
3)
\texttt{(2, 3)}
(2, 3),
(3,
4)
\texttt{(3, 4)}
(3, 4) 和
(4,
5)
\texttt{(4, 5)}
(4, 5)。
示例 3:
输入:
nums
=
[1,
3,
1,
5,
4],
k
=
0
\texttt{nums = [1, 3, 1, 5, 4], k = 0}
nums = [1, 3, 1, 5, 4], k = 0
输出:
1
\texttt{1}
1
解释:数组中只有一个
0
\texttt{0}
0-diff 数对,
(1,
1)
\texttt{(1, 1)}
(1, 1)。
数据范围
- 1 ≤ nums.length ≤ 10 4 \texttt{1} \le \texttt{nums.length} \le \texttt{10}^\texttt{4} 1≤nums.length≤104
- -10 7 ≤ nums[i] ≤ 10 7 \texttt{-10}^\texttt{7} \le \texttt{nums[i]} \le \texttt{10}^\texttt{7} -107≤nums[i]≤107
- 0 ≤ k ≤ 10 7 \texttt{0} \le \texttt{k} \le \texttt{10}^\texttt{7} 0≤k≤107
解法
思路和算法
由于题目要求计算数组 nums \textit{nums} nums 中的不同的差为 k k k 的数对的数目,因此只需要考虑数组中有哪些数字,不需要考虑顺序。
计算差为 k k k 的数对的数目需要考虑两种情况,分别是 k = 0 k = 0 k=0 和 k > 0 k > 0 k>0。
当 k = 0 k = 0 k=0 时,每个差为 k k k 的数对由两个相等的整数组成,对于任意整数 num \textit{num} num,只有当 num \textit{num} num 在数组 nums \textit{nums} nums 中出现次数大于 1 1 1 次时,才有数对 ( num , num ) (\textit{num}, \textit{num}) (num,num)。遍历数组 nums \textit{nums} nums 并用哈希表记录每个数字的出现次数,然后遍历哈希表,对于哈希表中的每个数字,如果出现次数大于 1 1 1 次,则将数对的数目加 1 1 1。遍历哈希表结束之后即可得到差为 k k k 的数对的数目。
当 k > 0 k > 0 k>0 时,每个差为 k k k 的数对由两个不相等的整数组成,对于任意整数 num \textit{num} num,当 num \textit{num} num 和 num + k \textit{num} + k num+k 都在数组中出现时,有数对 ( num , num + k ) (\textit{num}, \textit{num} + k) (num,num+k)。遍历数组 nums \textit{nums} nums 并用哈希集合记录出现的数字,然后遍历哈希集合,对于哈希集合中的每个数字 num \textit{num} num,如果 num + k \textit{num} + k num+k 也在哈希集合中,则将数对的数目加 1 1 1。遍历哈希集合结束之后即可得到差为 k k k 的数对的数目。
代码
class Solution {
public int findPairs(int[] nums, int k) {
int pairs = 0;
if (k == 0) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
Set<Integer> set = map.keySet();
for (int num : set) {
if (map.get(num) > 1) {
pairs++;
}
}
} else {
Set<Integer> set = new HashSet<Integer>();
for (int num : nums) {
set.add(num);
}
for (int num : set) {
if (set.contains(num + k)) {
pairs++;
}
}
}
return pairs;
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。需要遍历数组一次,使用哈希表或哈希集合存储数组中的不同数字,然后遍历哈希表或哈希集合一次,由于哈希表或哈希集合中的元素个数不超过数组长度,因此时间复杂度是 O ( n ) O(n) O(n)。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。需要使用哈希表或哈希集合存储数组中的不同数字,最坏情况下需要存储数组中的全部数字。