Count Inversions
Count Inversions is a medium arrays & hashing problem solved with the merge sort like approach pattern.
The best approach, optimal (merge sort and count), runs in O(n log n) time and O(n) space.
Below are 2 approaches in Java, from brute force up.
Problem
Two indices i < j form an inversion when arr[i] > arr[j]. Count the inversions in the array. The count measures how far the array is from being sorted.
Examples
Example 1
- Input
arr = [5, 3, 2, 4, 1]- Output
8- Why
- (5,3) (5,2) (5,4) (5,1) (3,2) (3,1) (2,1) (4,1).
Example 2
- Input
arr = [1, 2, 3]- Output
0
Constraints
1 <= arr.length <= 10^51 <= arr[i] <= 10^4- The count can exceed 32 bits; use a long.
Animated walkthrough
A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.
Concepts first, then the problem and every approach, step by step.
Space to play or pause · ← → to jump a step · click or drag the bar to seek
Solutions
Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.
| Approach | Time | Space |
|---|---|---|
| Brute force | O(n²) | O(1) |
| Optimal (merge sort and count) | O(n log n) | O(n) |
1Brute force
O(n²)O(1)Check every pair i < j and count those with arr[i] > arr[j].
- Two nested loops, count arr[i] > arr[j].
class Solution {
static long inversionCount(int[] arr) {
long count = 0;
for (int i = 0; i < arr.length; i++)
for (int j = i + 1; j < arr.length; j++)
if (arr[i] > arr[j]) count++;
return count;
}
}2Optimal (merge sort and count)
O(n log n)Standard merge sort: log n levels, O(n) work each.O(n)Temporary array used during merging.Merge sort the array. While merging two sorted halves, if the right element is smaller than the left element, it is also smaller than every remaining element in the left half, so it adds mid - i + 1 inversions in one step.
- Recursively sort and count each half.
- Merge; when right[j] < left[i], add (mid - i + 1).
- Sum the counts from both halves and the merge.
class Solution {
static long inversionCount(int[] arr) {
return sort(arr, new int[arr.length], 0, arr.length - 1);
}
private static 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;
tmp[k++] = a[j++];
}
}
while (i <= mid) tmp[k++] = a[i++];
while (j <= hi) tmp[k++] = a[j++];
for (k = lo; k <= hi; k++) a[k] = tmp[k];
return count;
}
}Edge cases to test
- Sorted array (0) and reverse-sorted array (n(n - 1) / 2)
- Equal values are not inversions
Hints
Hint 1
During a merge, when you take an element from the right half, how many left-half elements does it jump over?
FAQ
What is the best time complexity for Count Inversions?
Optimal (merge sort and count) runs in O(n log n) time and O(n) extra space. Standard merge sort: log n levels, O(n) work each.
Which pattern does Count Inversions use?
It is a arrays & hashing problem that uses the merge sort like approach pattern. Other problems with the same pattern: Arranging the array.
Is there a brute force solution for Count Inversions?
Yes. Brute force takes O(n²) time and O(1) space. Check every pair i < j and count those with arr[i] arr[j].
Which edge cases should I test for Count Inversions?
Sorted array (0) and reverse-sorted array (n(n - 1) / 2); Equal values are not inversions.