2006. Count Number of Pairs With Absolute Difference K
Problem Description
You are given an integer array nums
and an integer k
. Your task is to count how many pairs of indices (i, j)
exist where i < j
and the absolute difference between the elements at these indices equals k
.
In other words, you need to find all pairs where:
- The first index
i
comes before the second indexj
(i.e.,i < j
) - The absolute difference
|nums[i] - nums[j]|
equals exactlyk
The absolute value |x|
is defined as:
x
ifx >= 0
-x
ifx < 0
For example, if nums = [1, 2, 2, 1]
and k = 1
, the valid pairs would be:
(0, 1)
because|1 - 2| = 1
(0, 2)
because|1 - 2| = 1
(2, 3)
because|2 - 1| = 1
(1, 3)
because|2 - 1| = 1
So the answer would be 4.
The solution uses a brute force approach by checking every possible pair (i, j)
where i < j
, calculating the absolute difference, and counting those pairs where the difference equals k
. This is feasible because the array length is limited to at most 200 elements.
Intuition
Since we need to find pairs (i, j)
where i < j
and |nums[i] - nums[j]| == k
, the most straightforward approach is to check every possible pair.
The key observation is that the array size is constrained to be relatively small (at most 200 elements). This means we can afford to check all possible pairs without worrying about time complexity. With n
elements, there are n * (n-1) / 2
possible pairs to check, which for n = 200
gives us at most 19,900 comparisons - a manageable number for modern computers.
For each pair (i, j)
where i < j
, we simply:
- Calculate the absolute difference between
nums[i]
andnums[j]
- Check if this difference equals
k
- If yes, increment our counter
The nested loop structure naturally ensures we only consider pairs where i < j
- the outer loop picks the first index i
, and the inner loop starts from i + 1
to pick the second index j
. This avoids counting the same pair twice and ensures we maintain the ordering constraint.
The solution leverages Python's generator expression with sum()
to concisely count all valid pairs. The expression abs(nums[i] - nums[j]) == k
evaluates to True
(counted as 1) or False
(counted as 0), and summing these boolean values gives us the total count of valid pairs.
Solution Approach
The solution implements a brute force enumeration approach to count all valid pairs.
Algorithm Steps:
-
Get the array length: Store
n = len(nums)
to know the bounds for our iteration. -
Enumerate all pairs: Use two nested loops to generate all possible pairs
(i, j)
wherei < j
:- Outer loop:
i
ranges from0
ton-1
- Inner loop:
j
ranges fromi+1
ton
- Outer loop:
-
Check each pair: For each pair
(i, j)
, calculateabs(nums[i] - nums[j])
and check if it equalsk
. -
Count valid pairs: Use Python's
sum()
function with a generator expression to count how many pairs satisfy the condition.
Implementation Details:
The code uses a compact one-liner with nested comprehensions:
sum(abs(nums[i] - nums[j]) == k for i in range(n) for j in range(i + 1, n))
This generator expression:
- Iterates through all
i
from0
ton-1
- For each
i
, iterates through allj
fromi+1
ton-1
- Evaluates
abs(nums[i] - nums[j]) == k
which returnsTrue
(1) orFalse
(0) - Sums all the boolean values to get the total count
Time Complexity: O(n²)
where n
is the length of the array, as we check every pair exactly once.
Space Complexity: O(1)
as we only use a constant amount of extra space for the counter and loop variables.
The beauty of this solution lies in its simplicity - since the problem constraints allow for a quadratic solution (small array size), we can avoid more complex approaches like hash maps or sorting, and directly count the pairs that satisfy our condition.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with nums = [3, 1, 4, 1, 5]
and k = 2
.
Step 1: Initialize
- Array length
n = 5
- We need to find pairs where
|nums[i] - nums[j]| == 2
Step 2: Enumerate all pairs where i < j
Let's check each pair systematically:
-
i = 0 (nums[0] = 3):
- j = 1: |3 - 1| = 2 ✓ (equals k, count it!)
- j = 2: |3 - 4| = 1 ✗
- j = 3: |3 - 1| = 2 ✓ (equals k, count it!)
- j = 4: |3 - 5| = 2 ✓ (equals k, count it!)
-
i = 1 (nums[1] = 1):
- j = 2: |1 - 4| = 3 ✗
- j = 3: |1 - 1| = 0 ✗
- j = 4: |1 - 5| = 4 ✗
-
i = 2 (nums[2] = 4):
- j = 3: |4 - 1| = 3 ✗
- j = 4: |4 - 5| = 1 ✗
-
i = 3 (nums[3] = 1):
- j = 4: |1 - 5| = 4 ✗
Step 3: Count valid pairs We found 3 valid pairs:
- (0, 1): |3 - 1| = 2
- (0, 3): |3 - 1| = 2
- (0, 4): |3 - 5| = 2
Result: 3
The solution code sum(abs(nums[i] - nums[j]) == k for i in range(n) for j in range(i + 1, n))
performs exactly this process - it generates each pair once, checks if the absolute difference equals k, and counts how many times this condition is true.
Solution Implementation
1class Solution:
2 def countKDifference(self, nums: List[int], k: int) -> int:
3 """
4 Count pairs (i, j) where i < j and |nums[i] - nums[j]| == k
5
6 Args:
7 nums: List of integers
8 k: Target absolute difference
9
10 Returns:
11 Number of valid pairs with absolute difference equal to k
12 """
13 n = len(nums)
14
15 # Iterate through all pairs (i, j) where i < j
16 # Count pairs where absolute difference equals k
17 count = sum(
18 abs(nums[i] - nums[j]) == k
19 for i in range(n)
20 for j in range(i + 1, n)
21 )
22
23 return count
24
1class Solution {
2 /**
3 * Counts the number of pairs (i, j) where i < j and |nums[i] - nums[j]| = k
4 *
5 * @param nums the input array of integers
6 * @param k the target absolute difference
7 * @return the count of valid pairs
8 */
9 public int countKDifference(int[] nums, int k) {
10 int count = 0;
11 int length = nums.length;
12
13 // Iterate through all possible pairs where i < j
14 for (int i = 0; i < length; i++) {
15 for (int j = i + 1; j < length; j++) {
16 // Check if the absolute difference equals k
17 if (Math.abs(nums[i] - nums[j]) == k) {
18 count++;
19 }
20 }
21 }
22
23 return count;
24 }
25}
26
1class Solution {
2public:
3 int countKDifference(vector<int>& nums, int k) {
4 // Get the size of the input array
5 int arraySize = nums.size();
6
7 // Initialize counter for pairs with difference k
8 int pairCount = 0;
9
10 // Iterate through each element as the first element of a pair
11 for (int i = 0; i < arraySize; ++i) {
12 // Compare with all elements after index i to avoid duplicate pairs
13 for (int j = i + 1; j < arraySize; ++j) {
14 // Check if absolute difference equals k
15 // If true, increment counter (implicit conversion from bool to int)
16 pairCount += (abs(nums[i] - nums[j]) == k);
17 }
18 }
19
20 // Return the total count of valid pairs
21 return pairCount;
22 }
23};
24
1/**
2 * Counts the number of pairs (i, j) where i < j and |nums[i] - nums[j]| = k
3 * @param nums - Array of integers
4 * @param k - Target absolute difference
5 * @returns Number of valid pairs
6 */
7function countKDifference(nums: number[], k: number): number {
8 // Initialize counter for valid pairs
9 let pairCount: number = 0;
10
11 // Map to store frequency of each number seen so far
12 const frequencyMap: Map<number, number> = new Map<number, number>();
13
14 // Iterate through each number in the array
15 for (const currentNum of nums) {
16 // Check for pairs with difference k
17 // Count pairs where current number minus k exists (currentNum - k = previousNum)
18 // Count pairs where current number plus k exists (currentNum + k = previousNum)
19 pairCount += (frequencyMap.get(currentNum - k) || 0) + (frequencyMap.get(currentNum + k) || 0);
20
21 // Update frequency of current number in the map
22 frequencyMap.set(currentNum, (frequencyMap.get(currentNum) || 0) + 1);
23 }
24
25 return pairCount;
26}
27
Time and Space Complexity
The time complexity is O(n^2)
, where n
is the length of the array nums
. This is because the code uses two nested loops - the outer loop runs from i = 0
to n-1
, and for each i
, the inner loop runs from j = i+1
to n-1
. The total number of pairs checked is n*(n-1)/2
, which simplifies to O(n^2)
.
The space complexity is O(1)
. The code only uses a constant amount of extra space for the loop variables i
and j
, and the generator expression is evaluated lazily without creating an intermediate list. The sum()
function accumulates the result using constant space.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Counting Pairs Twice by Not Enforcing i < j
The Pitfall: A frequent mistake is to use two nested loops that both iterate from 0 to n, leading to counting each pair twice and also comparing an element with itself:
# INCORRECT - counts pairs twice and includes i == j
count = 0
for i in range(n):
for j in range(n): # Wrong! Should start from i+1
if abs(nums[i] - nums[j]) == k:
count += 1
This would count the pair (i, j) and also (j, i) as separate pairs, and when i == j, it compares an element with itself.
The Solution:
Always ensure the inner loop starts from i + 1
to maintain the constraint i < j
:
# CORRECT - each pair counted exactly once
count = 0
for i in range(n):
for j in range(i + 1, n): # Correct! Starts from i+1
if abs(nums[i] - nums[j]) == k:
count += 1
2. Misunderstanding Absolute Difference
The Pitfall: Some might incorrectly check only one direction of the difference:
# INCORRECT - only checks nums[i] - nums[j], not the absolute value if nums[i] - nums[j] == k: count += 1
This misses valid pairs where nums[j] > nums[i]
.
The Solution:
Always use abs()
or check both conditions:
# CORRECT - Option 1: Using abs()
if abs(nums[i] - nums[j]) == k:
count += 1
# CORRECT - Option 2: Checking both directions explicitly
if nums[i] - nums[j] == k or nums[j] - nums[i] == k:
count += 1
3. Off-by-One Error in Loop Boundaries
The Pitfall: Using incorrect loop boundaries that either miss pairs or cause index out of bounds:
# INCORRECT - misses the last element
for i in range(n - 1):
for j in range(i + 1, n - 1): # Wrong! Should go to n
...
# INCORRECT - potential index out of bounds
for i in range(n):
for j in range(i + 1, n + 1): # Wrong! Goes beyond array bounds
...
The Solution: Use the correct boundaries:
# CORRECT
for i in range(n): # or range(n - 1) since last element has no pairs
for j in range(i + 1, n): # Goes up to n-1 (inclusive)
...
What data structure does Breadth-first search typically uses to store intermediate states?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!