Problem
Given an integer array nums
and an integer k
, return the number of pairs (i, j)
where i < j
such that |nums[i] - nums[j]| == k
.
The value of |x|
is defined as:
x
ifx >= 0
.-x
ifx < 0
.
Examples
Example 1:
Input: nums = [1,2,2,1], k = 1
Output: 4
Explanation: The pairs with an absolute difference of 1 are:
- [1̲,2̲,2,1]
- [1̲,2,2̲,1]
- [1,2̲,2,1̲]
- [1,2,2̲,1̲]
Example 2:
Input:
nums = [1,3], k = 3
Output:
0
Explanation: There are no pairs with an absolute difference of 3.
Example 3:
Input: nums = [3,2,1,5,4], k = 2
Output: 3
Explanation: The pairs with an absolute difference of 2 are:
- [3̲,2,1̲,5,4]
- [3̲,2,1,5̲,4]
- [3,2̲,1,5,4̲]
Solution
Method 1 - Naive
A simple but inefficient solution involves performing a linear search for each element e1
to find e2 = e1 + k
in the rest of the array, resulting in an O(n^2)
time complexity. However, we can improve upon this.
Method 2 - Using HashMap
Here is the approach:
- Use a HashMap:
- We can use a
HashMap
to keep track of the frequency of each element innums
as we iterate through the array. - For each element
num
innums
, check if(num + k)
or(num - k)
exists in theHashMap
. - If it does, increment the result by the frequency of those elements.
- Add the current element to the
HashMap
.
- We can use a
- Count Pairs:
- As we iterate, for each element
num
, ifnum + k
ornum - k
exists, it means there are pairs that satisfy the condition.
- As we iterate, for each element
Code
Java
public class Solution {
public int countKDifference(int[] nums, int k) {
HashMap<Integer, Integer> freqMap = new HashMap<>();
int count = 0;
for (int num : nums) {
if (freqMap.containsKey(num + k)) {
count += freqMap.get(num + k);
}
if (freqMap.containsKey(num - k)) {
count += freqMap.get(num - k);
}
freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
}
return count;
}
}
Python
def countKDifference(nums, k):
freq_map = {}
count = 0
for num in nums:
if num + k in freq_map:
count += freq_map[num + k]
if num - k in freq_map:
count += freq_map[num - k]
if num in freq_map:
freq_map[num] += 1
else:
freq_map[num] = 1
return count
Complexity
- Time:
O(n)
, where (n) is the number of elements in the arraynums
, since we are iterating through the array and using aHashMap
for constant timeget
andput
operations. - Space:
O(n)
as we are storing elements in aHashMap
.
Method 3 - Using Hashset
Here are the steps:
- Use a HashSet to store the elements seen during a single pass through the array.
- For each element
e
, check if(e-K)
or(e+K)
is already in the HashSet. If so, increment a count. - Add the current element
e
to the HashSet.
Code
Java
public class Solution {
public int countKDifference(final int[] A, final int K) {
final HashSet<Integer> hs = new HashSet<>();
int count = 0;
for (int i = 0; i < A.length; i++) {
if (hs.contains(A[i] - K)) {
count++;
}
if (hs.contains(A[i] + K)) {
count++;
}
hs.add(A[i]);
}
return count;
}
}
Python
def countKDifference(nums, k):
seen = set()
count = 0
for num in nums:
if (num - k) in seen:
count += 1
if (num + k) in seen:
count += 1
seen.add(num)
return count
Method 4 - Using Sorting
If space is limited, an alternative solution uses O(1)
space and O(n log k)
time. Instead of a linear search for e2 = e1 + k
, we employ an optimal binary search.
- Sort the array, which takes
O(n log n)
time. - For each element
e1
in the sorted array, search for an elemente2 > e1
such thatA[e2] - A[e1] = k
.
By performing a binary search for e2
from e1 + 1
to e1 + diff
in the sorted array, we limit our search to O(log k)
time for each element. The overall time complexity becomes O(n log n) + O(n log k)
. If k > n
, the time complexity of this algorithm is O(n log k)
with O(1)
space.
For finding pairs with the minimum difference, you can refer to the solution in Min difference pairs.
Code
Java
public class Solution {
public int countKDifference(final int[] A, final int diff) {
Arrays.sort(A);
int count = 0;
for (int i = 0; i < A.length; i++) {
int matchKey = A[i] + diff;
int matchIndex = binarySearch(A, Math.min(i + 1, A.length - 1),
Math.min(i + diff, A.length - 1), matchKey);
count += (matchIndex != -1) ? 1 : 0;
}
return count;
}
private int binarySearch(final int[] A, int l, int r, final int key) {
while (l <= r) {
int m = (l + r) / 2;
if (A[m] == key) {
return m;
} else if (key < A[m]) {
r = m - 1;
} else {
l = m + 1;
}
}
return -1;
}
}
Python
def countKDifference(arr, diff):
arr.sort()
count = 0
for i in range(len(arr)):
match_key = arr[i] + diff
left = min(i + 1, len(arr) - 1)
right = min(i + diff, len(arr) - 1)
if binary_search(arr, left, right, match_key) != -1:
count += 1
return count
def binary_search(arr, left, right, key):
while left <= right:
mid = (left + right) // 2
if arr[mid] == key:
return mid
elif arr[mid] < key:
left = mid + 1
else:
right = mid - 1
return -1
Complexity
- ⏰ Time complexity:
O(n log k)
- 🧺 Space complexity:
O(1)