Count Number of Pairs With Absolute Difference K
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:
xifx >= 0.-xifx < 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
HashMapto keep track of the frequency of each element innumsas we iterate through the array. - For each element
numinnums, 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 + kornum - kexists, 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 aHashMapfor constant timegetandputoperations. - 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
eto 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
e1in the sorted array, search for an elemente2 > e1such 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](minimum-absolute-difference).
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)