Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
The closest two numbers in value are always adjacent once the array is sorted, so you never need to compare all pairs. Sort ascending, then scan consecutive pairs and return the smallest `|arr[i+1] − arr[i]|`. O(n log n) from the sort, O(n) for the scan.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you avoid the naive O(n²) all-pairs comparison by recognising that sorting makes the closest pair adjacent.
Where candidates slip
Comparing every pair with a double loop, or forgetting to sort and then wrongly assuming adjacency in the original order.
How to stand out
Justify adjacency in one line: for any non-adjacent sorted pair (i, j), the elements between them are squeezed in value, so some adjacent pair has a difference no larger — checking neighbours suffices.
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 previewClosest two valuesCan we reorder the array?NoYesExplore 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 — Compare Every Pair
1Hint 1Explore hintHide hint
The minimum difference is over all pairs. What's the most direct way to consider every pair?
2Hint 2Explore hintHide hint
Two nested loops: for each i, for each j > i, track the smallest |arr[i] − arr[j]|.
3Hint 3Explore hintHide hint
This is correct but quadratic. Is there structure that lets you avoid most of these comparisons?
A · Core idea
Look at every unordered pair (i, j) with j > i, compute |arr[i] − arr[j]|, and keep the smallest seen.
Why it's the natural first move. The problem is defined over all pairs, so enumerating all pairs is the most faithful translation. It needs no insight and is trivially correct.
Why `j` starts at `i + 1`. Starting the inner loop above i visits each unordered pair once and never compares an element with itself (which would give a meaningless 0). It's the same loop hygiene as in Two Sum's brute force.
Why we don't ship it. With n = 10⁵, the pair count is ~5 billion — far too slow. The win comes from realising we don't need distant pairs at all: after sorting, the closest two values must be neighbours, so a single linear sweep replaces the nested loops.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
arr = [3, -7, 0]i=0, j=1
|3 − (−7)| = 10
best = 103C · Code with teaching comments
Reference implementation previewpublic int minimumAbsoluteDifference(int[] arr) { int best = Integer.MAX_VALUE; for (int i = 0; i < arr.length; i++) { for (int j = i + 1; j < arr.length; j++) { best = Math.min(best, Math.abs(arr[i] - arr[j]));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 quadratic scan wastes effort comparing far-apart values that can never be the closest pair. Sorting exposes the only comparisons that can matter — adjacent ones — collapsing n²/2 checks into n−1.
ComplexityO(n²) time, O(1) space — n(n−1)/2 pairs, each compared in O(1); no extra storage beyond a running minimum.
E · Edge cases and pitfalls3Starting j at 0 — compares an element with itself, giving a false 0.Explore edge casesHide edge cases
Pitfalls
- Starting j at 0 — compares an element with itself, giving a false 0.
- Quadratic time times out for large n.
- Forgetting abs() — a signed difference can be negative and corrupt the minimum.
Approach 2 of 2 · Optimal
Sort + Adjacent Scan (Optimal)
1Hint 1Explore hintHide hint
If two numbers are close in value, where do they end up relative to each other once the array is sorted?
2Hint 2Explore hintHide hint
Sort ascending. The closest pair must be next to each other — otherwise a value squeezed between them would be even closer to one of them.
3Hint 3Explore hintHide hint
Scan i from 1 to n−1 and track the minimum of arr[i] − arr[i-1]. Since the array is sorted, that difference is already non-negative.
A · Core idea
Sort arr ascending, then sweep once comparing each element with its immediate predecessor. The minimum of arr[i] − arr[i-1] over i = 1 … n−1 is the answer.
Why the closest pair is adjacent after sorting — the proof. Sort the array so arr[0] ≤ arr[1] ≤ … ≤ arr[n-1]. Take any pair (i, j) with i < j. Their difference telescopes: arr[j] − arr[i] = (arr[i+1] − arr[i]) + (arr[i+2] − arr[i+1]) + … + (arr[j] − arr[j-1]). Every term on the right is a non-negative adjacent gap, and the whole sum is at least as large as any single term. So arr[j] − arr[i] is ≥ the smallest adjacent gap in that range. Therefore no non-adjacent pair can beat the best adjacent pair — checking neighbours is enough.
Why we can drop the absolute value. After sorting, arr[i] ≥ arr[i-1], so arr[i] − arr[i-1] is already ≥ 0. The abs() from the brute force becomes unnecessary — a small but telling simplification that shows you understand the invariant.
Why negatives are no problem. Sorting orders by signed value, so [-7, 0, 3] is already in the right order and the adjacency argument applies unchanged. The gap 0 − (−7) = 7 is computed correctly because subtraction respects sign.
Why this is optimal in practice. We do n − 1 subtractions instead of n(n−1)/2. The only cost above linear is the sort, which is unavoidable in the comparison model for revealing adjacency. For n = 10⁵ this is microseconds versus billions of operations.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
arr = [1, -3, 71, 68, 17]Array state
i=1
1 − (−3) = 4 → best 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
The telescoping argument is the heart of it: any gap is a sum of adjacent gaps, so the global minimum gap is a minimum over adjacent gaps. This 'distant differences decompose into adjacent ones' idea is why sorting helps so many spread/closeness problems — once sorted, locality of value equals locality of position.
ComplexityO(n log n) time, O(1) space — Sorting costs O(n log n) and dominates; the single neighbour scan is O(n) with O(1) extra space (in-place sort aside).
E · Edge cases and pitfalls6arr = [5, 5] — Sorted [5,5]; adjacent gap 0 — duplicates give the minimum possible answer.Explore edge casesHide edge cases
Edge cases handled
arr = [5, 5]Sorted [5,5]; adjacent gap 0 — duplicates give the minimum possible answer.arr = [-10, -10, 0]Sorted [-10,-10,0]; first gap is 0, which wins immediately.arr = [1000000000, -1000000000]Only one pair; gap 2·10⁹ — fits in a long if you compute it as long, or in int range arithmetic carefully.
Pitfalls
- Forgetting to sort and assuming adjacency in the original order.
- Starting the scan at i = 0 — arr[i-1] is out of bounds.
- Keeping abs() and then mishandling — harmless here but signals you missed that sorted gaps are non-negative.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int minimumAbsoluteDifference(int[] arr) { Arrays.sort(arr); int best = Integer.MAX_VALUE; for (int i = 1; i < arr.length; i++) { best = Math.min(best, arr[i] - arr[i - 1]);Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Skipping the sort
Adjacency only implies closeness after sorting. Scanning neighbours of the raw array compares unrelated values and misses the true minimum.
Explore the code comparisonHide the code comparison
Skipping the sort
Adjacency only implies closeness after sorting. Scanning neighbours of the raw array compares unrelated values and misses the true minimum.
Don't write this
int best = Integer.MAX_VALUE;
for (int i = 1; i < arr.length; i++) {
best = Math.min(best, Math.abs(arr[i] - arr[i - 1]));
}Write this instead
Arrays.sort(arr);
int best = Integer.MAX_VALUE;
for (int i = 1; i < arr.length; i++) {
best = Math.min(best, arr[i] - arr[i - 1]);
}2Out-of-bounds on the first element
Accessing arr[i-1] with i starting at 0 reads index -1. Start the scan at i = 1.
Explore the code comparisonHide the code comparison
Out-of-bounds on the first element
Accessing arr[i-1] with i starting at 0 reads index -1. Start the scan at i = 1.
Don't write this
for i in range(len(arr)):
best = min(best, arr[i] - arr[i - 1])Write this instead
for i in range(1, len(arr)):
best = min(best, arr[i] - arr[i - 1])3Taking abs of the values, not the difference
The metric is |a − b|, not ||a| − |b||. Abs-ing values first turns -3 and 3 into the same number and reports a false 0.
Explore the code comparisonHide the code comparison
Taking abs of the values, not the difference
The metric is |a − b|, not ||a| − |b||. Abs-ing values first turns -3 and 3 into the same number and reports a false 0.
Don't write this
best = min(best, abs(arr[i]) - abs(arr[i - 1]))Write this instead
best = min(best, arr[i] - arr[i - 1])Revise
Carry the pattern into the interview
Pattern to remember
Sort then scan adjacent differences
Code pattern to memorize
sort(arr)
best = ∞
for i in 1 .. n-1:
best = min(best, arr[i] - arr[i-1])
return bestRules to remember
- 1After sorting, the minimum absolute difference is always between adjacent elements — no need to check distant pairs.
- 2Once sorted,
arr[i] − arr[i-1]is already non-negative, so you can drop theabs(). - 3Compare
n − 1adjacent pairs, not alln(n−1)/2pairs — that's the whole point. - 4Handle negatives correctly: sorting orders by value, so
[-2, 2, 4]gives gaps 4 and 2, not 0. - 5Use a wide type for the subtraction if values span the full int range —
−10⁹to10⁹differences fit in int, but be deliberate.
Use this pattern when
- Find the closest pair by value in a 1-D array
- Minimise a gap and the array can be reordered freely
- Any 'tightest pair / smallest spread' question on unstructured numbers
- You can afford an O(n log n) sort
Choose another pattern when
- You must preserve original indices/positions and can't sort → different approach
- Closest pair in 2-D / geometry → divide-and-conquer closest-pair, not this
- You need the closest pair to a query value repeatedly → sort once then binary search
- Difference defined on something other than value (e.g. index distance) → re-read
Interview takeaway
The closest two values are neighbours after sorting — a one-line fact that turns an O(n²) all-pairs scan into O(n log n). The same 'sort, then only adjacent matters' idea powers Max Min and many spread problems.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternSort then adjacent scan. Recognise it for any 'closest pair by value' on a reorderable 1-D array — sorting makes the answer a neighbour comparison. Same backbone as Max Min (window size k) and Minimum Absolute Difference in a BST.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Max MinComing soonGeneralise to picking k elements minimising max − min — slide a width-k window after sorting.
- Minimum Absolute Difference (BST)Coming soonSame idea on a BST: in-order traversal yields sorted values, then compare neighbours.
- K Closest ElementsComing soonSort or binary search, then a width-k window around the target.
- Two Sum IIAnother sorted-array two-pointer pairing problem.