GeeksforGeeks Hard

Count Inversions

Count Inversions is a GFG problem (Medium). Given an integer array arr, return its inversion count: the number of pairs (i, j) with i < j and arr[i] > arr[j].

  • The count measures how far the array is from sorted: 0 when sorted, n(n−1)/2 when reversed.
  • Equal values do not form an inversion.
  • With up to 10⁵ elements, checking every pair is too slow; the expected time is O(n log n).
Constraints
  • 1 ≤ arr.size() ≤ 10⁵
  • 1 ≤ arr[i] ≤ 10⁴
arraymerge-sortdivide-and-conquer
Open on GeeksforGeeks ↗
02

Intuition

Split the array into a left half and a right half. Every inversion is one of three kinds:

  • Both values in the left half, or both in the right half: the same problem on a smaller array, so recursion counts them.
  • One value in each half: counted while the two halves are merged.

The cross pairs are cheap to count once both halves are sorted. If a right value is smaller than the left value arr[i], it is also smaller than every left value after arr[i], and all of them come before it in the array. So it adds mid - i inversions in one step. That is the count inversions merge sort idea.

How to spot this pattern

"Count pairs i < j where the earlier value is larger" (or any order-based pair count) points to merge sort with a counter: each merge sees exactly the pairs that cross its two halves. The same idea solves Reverse Pairs (LeetCode 493, count before merging) and Count of Smaller Numbers After Self (LeetCode 315).

03

Approach

Try it first

Before reading on: merge [2, 4] with [1, 3, 5]. When 1 is taken from the right, how many values in the left half is it smaller than? Do you need to compare it with each of them?

1

Split and count each half

sort(lo, hi) returns the inversions inside arr[lo:hi] and leaves that range sorted. A range of one element has none. Otherwise it calls itself on both halves and adds their counts, so only pairs that cross the middle are left.

2

Merge with two pointers

i walks the left half and j the right one; each step moves the smaller value into merged.

  • arr[i] <= arr[j]: take arr[i]. No inversion, and ties count as none.
  • arr[j] < arr[i]: take arr[j] and add mid - i, one for each left value still waiting, since all of them are at least arr[i].
3

Copy the rest and write back

When one half runs out, append what is left of the other; those values form no new inversions. Then write merged into arr[lo:hi]. The range must end up sorted, because the parent merge relies on that to count in batches.

4

Return the total

sort(0, n) returns the inversion count. Each pair is counted once, in the merge where its two values first fall into different halves. There are log n levels of O(n) merging, so the time is O(n log n).

04

Count Inversions solution in Python | C++ | Java

▶1class Solution:
▶2 def inversionCount(self, arr):
▶3 def sort(lo, hi):
▶4 if hi - lo <= 1:
▶5 return 0
▶6 mid = (lo + hi) // 2
▶7 inv = sort(lo, mid) + sort(mid, hi)
▶8 merged = []
▶9 i, j = lo, mid
▶10 while i < mid and j < hi:
▶11 if arr[i] <= arr[j]:
▶12 merged.append(arr[i])
▶13 i += 1
▶14 else:
▶15 inv += mid - i
▶16 merged.append(arr[j])
▶17 j += 1
▶18 merged += arr[i:mid] + arr[j:hi]
▶19 arr[lo:hi] = merged
▶20 return inv
▶21 
▶22 return sort(0, len(arr))
arr2041123354count0split until halves have 1 element
arr[2, 4, 1, 3, 5]
count0
Start. sort(0, n) splits the array in half again and again. A piece of one element is sorted and holds no inversions, so the real work happens on the way back up, when two sorted halves are merged.
arr2041123354ijleftrightmergedcount0merge [2] with [4]
left[2]sorted
right[4]sorted
count0
Both recursive calls have returned, so [2] and [4] are each sorted and their own inversions are already counted. What is left are the pairs with one value in each half; the merge finds them.
arr2041123354ijleftrightmerged2count02 ≤ 4 → take 2, no inversion
left[i]2
right[j]4
count0
2 from the left is not larger than 4, so it goes first. It already sits before every right-half value it is smaller than or equal to, so it adds no inversion.
arr2041123354jleftrightmerged24count0one side used up → copy [4]
leftover[4]
merged[2, 4]
count0
The left half ran out first. The right values still waiting are at least as large as every left value, so they form no inversions and are copied over as they are.
arr2041123354count0positions 0–1 now sorted
arr[2, 4, 1, 3, 5]
count0
Write the merged run back into arr. This piece is now sorted, which is exactly what the next merge up needs: the batch count mid − i is only correct when the left half is sorted.
arr2041123354ijleftrightmergedcount0merge [3] with [5]
left[3]sorted
right[5]sorted
count0
Both recursive calls have returned, so [3] and [5] are each sorted and their own inversions are already counted. What is left are the pairs with one value in each half; the merge finds them.
arr2041123354ijleftrightmerged3count03 ≤ 5 → take 3, no inversion
left[i]3
right[j]5
count0
3 from the left is not larger than 5, so it goes first. It already sits before every right-half value it is smaller than or equal to, so it adds no inversion.
arr2041123354jleftrightmerged35count0one side used up → copy [5]
leftover[5]
merged[3, 5]
count0
The left half ran out first. The right values still waiting are at least as large as every left value, so they form no inversions and are copied over as they are.
arr2041123354count0positions 3–4 now sorted
arr[2, 4, 1, 3, 5]
count0
Write the merged run back into arr. This piece is now sorted, which is exactly what the next merge up needs: the batch count mid − i is only correct when the left half is sorted.
arr2041123354ijleftrightmergedcount0merge [1] with [3, 5]
left[1]sorted
right[3, 5]sorted
count0
Both recursive calls have returned, so [1] and [3, 5] are each sorted and their own inversions are already counted. What is left are the pairs with one value in each half; the merge finds them.
arr2041123354ijleftrightmerged1count01 ≤ 3 → take 1, no inversion
left[i]1
right[j]3
count0
1 from the left is not larger than 3, so it goes first. It already sits before every right-half value it is smaller than or equal to, so it adds no inversion.
arr2041123354jleftrightmerged135count0one side used up → copy [3, 5]
leftover[3, 5]
merged[1, 3, 5]
count0
The left half ran out first. The right values still waiting are at least as large as every left value, so they form no inversions and are copied over as they are.
arr2041123354count0positions 2–4 now sorted
arr[2, 4, 1, 3, 5]
count0
Write the merged run back into arr. This piece is now sorted, which is exactly what the next merge up needs: the batch count mid − i is only correct when the left half is sorted.
arr2041123354ijleftrightmergedcount0merge [2, 4] with [1, 3, 5]
left[2, 4]sorted
right[1, 3, 5]sorted
count0
Both recursive calls have returned, so [2, 4] and [1, 3, 5] are each sorted and their own inversions are already counted. What is left are the pairs with one value in each half; the merge finds them.
arr2041123354ijleftrightmerged1count0+2=21 < 2 → 2 inversions at once
right[j]1
left still waiting[2, 4]
count2
1 from the right is smaller than 2. The left half is sorted, so it is smaller than every left value still waiting too: [2, 4]. Each of those sits before it in the array, so all 2 pairs are inversions. Adding mid − i = 2 counts them in one step instead of one by one.
arr2041123354ijleftrightmerged12count22 ≤ 3 → take 2, no inversion
left[i]2
right[j]3
count2
2 from the left is not larger than 3, so it goes first. It already sits before every right-half value it is smaller than or equal to, so it adds no inversion.
arr2041123354ijleftrightmerged123count2+1=33 < 4 → 1 inversion at once
right[j]3
left still waiting[4]
count3
3 from the right is smaller than 4. The left half is sorted, so it is smaller than every left value still waiting too: [4]. It sits before it in the array, so that pair is an inversion. Adding mid − i = 1 counts them in one step instead of one by one.
arr2041123354ijleftrightmerged1234count34 ≤ 5 → take 4, no inversion
left[i]4
right[j]5
count3
4 from the left is not larger than 5, so it goes first. It already sits before every right-half value it is smaller than or equal to, so it adds no inversion.
arr2041123354jleftrightmerged12345count3one side used up → copy [5]
leftover[5]
merged[1, 2, 3, 4, 5]
count3
The left half ran out first. The right values still waiting are at least as large as every left value, so they form no inversions and are copied over as they are.
arr1021324354count3positions 0–4 now sorted
arr[1, 2, 3, 4, 5]
count3
Write the merged run back into arr. This piece is now sorted, which is exactly what the next merge up needs: the batch count mid − i is only correct when the left half is sorted.
arr1021324354count3return 3
inversions3
Answer: 3. Every pair was counted exactly once, in the merge where its two values first met in different halves. The array also ends up sorted, as a side effect of the merge sort.
05

Brute force (every pair)

For each index i, look at every later index j and count the pairs where arr[i] > arr[j].

▶1class Solution:
▶2 def inversionCount(self, arr):
▶3 n = len(arr)
▶4 count = 0
▶5 for i in range(n):
▶6 for j in range(i + 1, n):
▶7 if arr[i] > arr[j]:
▶8 count += 1
▶9 return count
06

Common pitfalls

Adding 1 instead of mid - i

✗ Wrong
else:
    inv += 1
✓ Right
else:
    inv += mid - i

The right value is smaller than every left value still waiting, not just arr[i]. On [2, 4, 1, 3, 5] adding 1 per step returns 2 instead of 3.

Using < so ties go to the counting branch

✗ Wrong
if arr[i] < arr[j]:
✓ Right
if arr[i] <= arr[j]:

Equal values are not an inversion. With <, [10, 10, 10] reports 1 instead of 0.

Forgetting the counts from the halves

✗ Wrong
inv = 0
✓ Right
inv = sort(lo, mid) + sort(mid, hi)

The merge only sees pairs that cross the middle. Pairs inside each half were counted by the recursive calls, and dropping them gives only the top-level cross pairs.

07

Edge cases

Reverse sorted

Every pair is inverted, n(n − 1) / 2 in total. For n = 10⁵ that is about 5 × 10⁹, past a 32-bit int, so keep the count in a long / long long.

08

Complexity

Time
O(n log n)
Space
O(n)
log n levels of recursion, each merging n values in total. The merge buffer is O(n). The C++ and Java code adds in 64 bits and casts at the end, because GFG's signature returns an int.
09

Count Inversions FAQ

Does counting inversions with merge sort change the array?

Yes, arr ends up sorted. If the caller still needs the original order, run the count on a copy (arr[:] in Python, arr.clone() in Java).

Can a Fenwick tree count inversions in an array?

Yes. Scan from right to left, and for each value ask the Fenwick tree how many smaller values were already seen, then add the value. With values up to 10⁴ that is also O(n log n), but merge sort needs no extra structure.