Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Count the pairs of elements whose difference is exactly k. Sort the array, then for each value x do a binary search for x + k; every hit is one valid pair. Sorting makes the lookup O(log n), so the whole thing is O(n log n). Because the values are distinct, each pair is found exactly once (search forward for the larger partner). A sorted two-pointer sweep is the equivalent O(n)-after-sort alternative.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you move from the O(n²) all-pairs scan to a sorted structure that answers 'does x + k exist?' in O(log n) — and whether you avoid double counting by searching only for the larger partner.
Where candidates slip
Searching for both x + k and x − k (double counting each pair), comparing |a − b| in a nested loop and timing out, or using an exact search where the values aren't sorted.
How to stand out
Note that searching only for x + k counts each pair once by construction, then offer the two-pointer sweep as an even cleaner O(n)-after-sort variant and mention a hash set as an O(n) average alternative.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachFirst decision previewSort the arrayFound?YesNoExplore the full treeCollapse the tree
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Brute Force — All Pairs
1Hint 1Explore hintHide hint
What's the most direct way to test whether two elements differ by exactly k?
2Hint 2Explore hintHide hint
Compare every unordered pair (i, j) with i < j and check if their difference equals k.
3Hint 3Explore hintHide hint
Increment a counter on each match; no early exit since we want the total count.
A · Core idea
The literal reading: a valid pair is two elements whose difference is k. Enumerate every unordered pair and count the matches.
Why i < j. Starting the inner loop at i + 1 visits each unordered pair once and never compares an element with itself, so we don't double count or self-match.
Why absolute difference. Using Math.abs(arr[i] − arr[j]) == k handles either ordering of the two values within the pair.
Why we don't ship it. With n up to 10⁵, n²/2 ≈ 5×10⁹ comparisons is too slow. Sorting plus binary search (or a single hash-set pass) brings it down dramatically.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
arr = [1, 5, 3, 4, 2], k = 2Array state
i=3 (4)
|4 − 2| = 2 → count++
3C · Code with teaching comments
Reference implementation previewpublic int pairsBrute(int[] arr, int k) { int n = arr.length, count = 0; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (Math.abs((long) arr[i] - arr[j]) == k) {Explore the full codeHide the full code
D · Why it works and complexityO(n²) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The inner loop re-asks 'is there a partner for arr[i]?' by scanning everything. That repeated existence question is exactly what a sorted array + binary search (or a hash set) answers in sub-linear / constant time.
ComplexityO(n²) time, O(1) space — Two nested loops over all i < j → n(n−1)/2 ≈ n²/2 comparisons, O(n²).
E · Edge cases and pitfalls3Starting j at 0 — self-matches and double counts.Explore edge casesHide edge cases
Pitfalls
- Starting j at 0 — self-matches and double counts.
- Subtracting without widening to long — can overflow for large values.
- Running O(n²) on n = 10⁵ and timing out.
Approach 2 of 2 · Optimal
Sort + Binary Search (Optimal)
1Hint 1Explore hintHide hint
If the array were sorted, how could you check whether a specific partner value exists without scanning?
2Hint 2Explore hintHide hint
For each x, its larger partner is x + k. Binary search the sorted array for that exact value.
3Hint 3Explore hintHide hint
Count one for each successful search. Searching only for x + k (the larger side) counts each pair exactly once.
A · Core idea
Sort the array. Now every value x has a unique potential partner x + k (the larger element of the pair). Binary search the sorted array for x + k; each hit is one valid pair.
Why search for the larger partner only. A pair (x, x + k) could be discovered from either side — from x looking up for x + k, or from x + k looking down for x. To count it exactly once, we fix a direction: every value searches upward for x + k. The smaller member of each pair finds the larger; the larger member searches for an even larger value that completes a different pair (or none). No pair is counted twice and none is missed.
Why distinct values simplify it. Since all elements are distinct, a successful search means exactly one partner exists — the count increments by one, with no frequency multiplication.
Why exact match, not a boundary search. The difference must equal k exactly, so we need plain 'does x + k exist?' — an equality binary search. (If the problem asked for difference ≤ k, we'd switch to counting a range via two pointers.)
Overflow note. x + k can exceed 2³¹ since x < 2³¹ and k < 10⁹. Compute the key in a 64-bit type (long) before searching to avoid wraparound.
Two-pointer equivalent. On the sorted array, keep two indices i ≤ j: advance j while arr[j] − arr[i] < k; if it equals k, count and advance both; if it exceeds k, advance i. That's O(n) after the sort and avoids the per-element log factor — mention it as the streamlined alternative.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
arr = [1, 5, 3, 4, 2], k = 2Array state
x=3
search 3+2=5 → found at index 4
3C · Code with teaching comments
D · Why it works and complexityO(n log n) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
Sorting converts a quadratic 'find a partner for everyone' into a logarithmic existence test, and fixing the search direction (always look up for x + k) is the clean trick that prevents double counting without any extra bookkeeping. The same sort-then-search shape solves 'two sum on a sorted array' and 'count pairs with a given difference/sum'.
ComplexityO(n log n) time, O(1) space — Sorting is O(n log n). Then n binary searches at O(log n) each → O(n log n). No extra space beyond the sort (O(1) auxiliary).
E · Edge cases and pitfalls5arr = [10, 20, 30], k = 5 — No search for x+5 (15, 25, 35) succeeds → count 0.Explore edge casesHide edge cases
Edge cases handled
arr = [10, 20, 30], k = 5No search for x+5 (15, 25, 35) succeeds → count 0.arr = [1, 2], k = 1x=1 finds 2 → count 1; x=2 searches 3, not found. Total 1, counted once from the smaller side.
Pitfalls
- Also searching for x − k — counts every pair twice.
- Forgetting to widen x + k to long — overflow for large values.
- Using an exact search on an unsorted array — sort first.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int pairs(int[] arr, int k) { java.util.Arrays.sort(arr); int count = 0; for (int x : arr) { if (binarySearch(arr, (long) x + k)) {Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Double counting by searching both directions
If you look for both x + k and x − k, each pair is discovered from both members and counted twice. Fix one direction.
Explore the code comparisonHide the code comparison
Double counting by searching both directions
If you look for both x + k and x − k, each pair is discovered from both members and counted twice. Fix one direction.
Don't write this
if found(arr, x + k): count += 1
if found(arr, x - k): count += 1Write this instead
if found(arr, x + k): count += 1 # larger partner only2Exact search on unsorted data
Binary search assumes sorted order; running it on the raw input returns wrong (or random) results.
Explore the code comparisonHide the code comparison
Exact search on unsorted data
Binary search assumes sorted order; running it on the raw input returns wrong (or random) results.
Don't write this
// no sort
for (int x : arr) if (binarySearch(arr, (long) x + k)) count++;Write this instead
java.util.Arrays.sort(arr);
for (int x : arr) if (binarySearch(arr, (long) x + k)) count++;3Overflow on the partner value
x < 2³¹ and k < 10⁹, so x + k can exceed Integer.MAX_VALUE and wrap negative, breaking the search.
Explore the code comparisonHide the code comparison
Overflow on the partner value
x < 2³¹ and k < 10⁹, so x + k can exceed Integer.MAX_VALUE and wrap negative, breaking the search.
Don't write this
binarySearch(arr, x + k); // int + int can overflowWrite this instead
binarySearch(arr, (long) x + k); // 64-bit keyRevise
Carry the pattern into the interview
Pattern to remember
Sort, then binary-search for x + k (the larger partner)
Code pattern to memorize
sort(arr)
count = 0
for x in arr:
if binarySearch(arr, x + k) found:
count += 1
return countRules to remember
- 1Search for
x + k, the larger partner — each pair(x, x+k)is then discovered exactly once, from its smaller side. - 2The array values are distinct, so a found target is one unique pair (no multiplicity bookkeeping).
- 3Sort first: binary search and two-pointer both require sorted input.
- 4Difference is exact (
= k), not≤ k— use an exact-match search, not a boundary/upper-bound count. - 5Equivalent O(n) sweep: two pointers
i,j; advancejwhilearr[j] − arr[i] < k, count on equality, advanceiotherwise.
Use this pattern when
- Count pairs satisfying an exact additive relation in a set of distinct values
- You can sort, and each query becomes 'does value v exist?'
- A 'difference equals k' / 'sum equals target' count over a static array
Choose another pattern when
- Difference ≤ k (a range, not exact) → two-pointer window counting instead of exact search
- Duplicates allowed and pairs counted with multiplicity → use a frequency map, not a set
- Values fit in a small range → a boolean presence array beats sorting
Interview takeaway
Sorting turns 'find a partner with an exact difference' into an O(log n) existence query. Always search for the larger partner (x + k) so each pair is counted once — or sweep two pointers for the same result without per-element search overhead.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternSort-then-search for an exact partner: sorting turns 'find an element with a fixed difference/sum' into an O(log n) existence query, and fixing the search direction (look up for x + k) counts each pair once. The two-pointer sweep is the O(n)-after-sort equivalent. Same shape as Two Sum II and count-pairs-with-sum.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Pairs with difference at most kComing soonSwitch the exact search to a two-pointer window count over the sorted array.
- Two Sum II — Sorted ArrayComing soonSorted input, find a pair summing to target — two pointers or binary search.
- Count Pairs with Given SumComing soonSame idea for sums instead of differences — search for target − x or use a frequency map.