What it teaches: Piggyback on merge sort: when an element from the right half is merged first, it forms an inversion with every element left in the left half.
The problem
An inversion is a pair (i, j) with i < j and nums[i] > nums[j]. Return the number of inversions in nums.
Example 1
Input: nums = [2, 4, 1, 3, 5]
Output: 3
(2,1), (4,1), (4,3).
Example 2
Input: nums = [5, 4, 3, 2, 1]
Output: 10
Constraints
1 ≤ n ≤ 10⁵
Answer fits in a long
Pattern clues in the wording
→ Count pairs out of order
→ n up to 10⁵: O(n²) too slow
These clues point to Divide and Conquer: Split the input into halves, solve each half recursively, and combine the results.
Stuck? Take one hint at a time
Solution.java · starter
class Solution {
public long countInversions(int[] nums) {
return 0;
}
}
Write your solution locally or in your editor for now. The in-browser runner (Java first, then Python, C++ and more) will run these tests right here.
class Solution {
public long countInversions(int[] nums) {
long count = 0;
for (int i = 0; i < nums.length; i++)
for (int j = i + 1; j < nums.length; j++)
if (nums[i] > nums[j]) count++;
return count;
}
}
Verdict: 5 × 10⁹ pairs at the limit: too slow.
2
Optimal: merge sort with counting
Time O(n log n) Space O(n)
Merge as usual. When taking right[j] while left[i..mid] remain, add (mid − i + 1): all those remaining left elements are larger than right[j] and come before it.
Approach 2
class Solution {
public long countInversions(int[] nums) {
int[] a = nums.clone();
return sort(a, new int[a.length], 0, a.length - 1);
}
private long sort(int[] a, int[] tmp, int lo, int hi) {
if (lo >= hi) return 0;
int mid = (lo + hi) >>> 1;
long count = sort(a, tmp, lo, mid) + sort(a, tmp, mid + 1, hi);
int i = lo, j = mid + 1, k = lo;
while (i <= mid && j <= hi) {
if (a[i] <= a[j]) tmp[k++] = a[i++];
else {
count += mid - i + 1; // a[i..mid] are all > a[j]
tmp[k++] = a[j++];
}
}
while (i <= mid) tmp[k++] = a[i++];
while (j <= hi) tmp[k++] = a[j++];
System.arraycopy(tmp, lo, a, lo, hi - lo + 1);
return count;
}
}
Verdict: The classic divide-and-conquer counting trick.
Before you submit
Edge cases and common mistakes
Test these inputs
Sorted → 0
Reverse sorted → n(n − 1)/2
Duplicates (equal values aren't inversions)
Mistakes people make
Using < instead of <= in the merge (counts equal pairs).