Inversion Count in an Array

The Inversion count in an array indicates the number of element pairs (i, j) where i < j and A[i] > A[j], serving as a measure of the array's unsortedness. Understanding Inversion count in an Array is essential for analyzing sorting algorithms' efficiency and optimizing them, making count inversion a key concept in algorithm design and data analysis.
Problem Statement
Given an array containing integers. The problem is to find the number of inversions in the array . An inversion is defined as a pair such that and . We need to find the inversion count for the input array . Note that the array can contain duplicate elements.
Example 1
Output
Example Explanation 1
In this example, the inversion pairs are: as and . as and . as and . as and . Overall, we have inversion pairs.

Example 2
Output 6
Example Explanation 2
In this example, we have the following inversion pairs:
Example 3
Output 0
Example Explanation 3
In this example, there are no inversion pairs as for all .
Constraints
Approach 1: Brute-Force Solution
A simple approach to find the inversion count for the array is to consider every possible pair of indices and check whether this pair forms an inversion. We will maintain a variable to count the total number of inversion pairs. If this pair satisfies the conditions that and then increase the counter by 1.
Algorithm
Step 1: Iterate from to Step 2: Iterate from to : Step 3: If : Add to the answer.
We iterate the variable from to and the variable iterates from to . This guarantees that the condition is true. Now, if , we can guarantee that forms an inversion pair.
Example
For
For
For
For
For
For
Total count of inversion pairs =
Implementation in C++
Implementation in Java
Implementation in Python3
Complexity Analysis
Time Complexity
In the implementation, we are looking at all possible pairs and we check the condition whether this pair forms inversion pair or not. The total number of such pairs is . Hence the time complexity is Time Complexity:
Space Complexity
In this method, we only need a constant number of variables for iteration and to store the answer. Hence the space complexity is . Space Complexity:
Approach 2: Using Merge Sort
We can use a modified merge sort to count inversions in the array .
Merge Sort is a divide and conquer algorithm that divides array into two parts and then recursively sorts the left and right subparts. The conquer step merges the two sorted halves into a single array and returns the merged array as the final answer. This is done recursively for each sorted halves. Finally, we get the sorted array. We can use the same approach to find the total number of inversions in the array .
- We will recursively split the array into two halves. The total inversion pairs will be equal to the sum of inversion pairs in the two halves and the number of crossing inversions. Crossing inversion means pairs such that lies in one half and lies in the other.
- When we have calculated the inversion count in the two halves, we need to add the contribution of crossing inversions. To do this efficiently, we can use a two-pointer approach (explained below) on the sorted halves.
- So we want to calculate the inversion count as well as keep sorting left and right halves. This is similar to the Merge Sort (described above), hence we can modify the same algorithm to calculate the inversions in the array .
We can modify the merge function and find the inversion count using the same approach.
We will divide array into two equal parts. We will denote as the left half of array and as the right half of array . Try to think about how can we calculate the number of inversion pairs recursively such that lies in the left half of the array and lies in the right half of the array.
Suppose the left half has only one element and the right half has only one element. In this case, we can say that if , then the number of inversion pairs is else it will be . This is because we know that an element belonging to the array will have an index less than the element belonging to the array in the original array . This means the condition that is satisfied for these two elements, where and denote the index of and in array respectively.

Now consider that the size of the array left and right is , respectively. We know, Total inversions = Inversion count in the array + Inversion count in the array + Count of crossing inversion pairs from to . Here crossing inversion pairs means the pairs such that lies in the array and lies in the array . We are solving this problem recursively, hence we already know the count of inversion pairs in the array and the count of inversion pairs in the array . We need to count the number of inversion pairs such that lies in the array and lies in the array . The sum of inversion pairs in the array , the array , and the crossing inversions is equal to the total inversion pairs. The crossing inversions are calculated while merging the arrays and .

To do this, we will use the fact that the array and are two sorted arrays.
- In the merge function, we use two pointers and which iterates over the array and respectively.
- To merge them, we find the minimum of the two elements and . We append this minimum to the resulting array and increase the pointer accordingly.

While merging, we can calculate the inversion count simultaneously. To do this, observe that:
- The elements in the array will be present before the elements in the array in the array . This is because, in the divide step, we split the array into two parts from the middle and the left part ranges from to and the right part ranges from to . The half contains prefix elements of the array , while the right half contains suffix elements of the array .
- So, if there is an element such that , then this pair will form an inversion pair. Now since the array is sorted >= . This means > and the pair will also form an inversion pair.
- In general, we can say that all the elements in the array present after the index will form an inversion pair with if . The contribution of such pairs will be equal to the number of elements present in the range . The number of such elements will be . So, we can add to the answer. In this way, we can find the number of inversions in the merged array of size .
- At the end of the merge function, we return the total number of crossing inversion pairs.
Example
Let us say we want to find the number of crossing inversions and the two halves of the array A are: ,
Iteration 1:
, Initially ,
Iteration 2:
We add the contribution of all elements from with .

Iteration 3:
Iteration 5:
We add the contribution of with .

Iteration 6:
Iteration 7:

Finally we add the remaining elements. We get: In this way, we calculate the count of inversion pairs while computing the merged array.
Algorithm
MergeSort(arr, start, end)
- Divide the array arr into two halves: left and right.
- Assign mid = (start + end)/2
- = MergeSort(arr, start, mid)
- = MergeSort(arr, mid + 1, end)
- = Merge(arr, start, mid, end)
- return
Merge(arr, start, mid, end):
- Initialize
- while and :
- If :
- Append to temp
- Else:
- Append to temp
- Increment by
- return
- If :
Now let us look at the implementation. We will implement this by modifying the Merge Sort algorithm to find the inversion count as discussed in the algorithm above.
C++ Implementation
Java Implementation
Python3 Implementation
Complexity Analysis
Time Complexity
In this method, we are dividing a given array into two equal parts recursively and calculate the inversion count in the two halves separately. Then we are calculating the crossing inversions using the Merge function described above. So we can the recurrence relation as: . We can solve this as:
T(N) = 2T(N/2) + N
= 2(2T(N/4) + N/2) + N
= 4T(N/4) + N + N = 4T(N/4) + 2N
= 8T(N/8) + 3N
...
...
= N*T(1) + log2(N)*N
= O(N*log2(N))
Time Complexity:
Space Complexity
In this method, in the Merge function, we are using a temporary array to merge the two halves of array A. At any recursive call, the size of the temporary array is bounded by the size of the array , so we need at most memory for the temporary array. We are also doing a recursion. The maximum recursion depth is bounded by . Hence total memory needed is Space Complexity:
Approach 3: Using Heap Sort + Bisection
In the above methods, to find the inversion pair , we guaranteed that and then we counted all the pairs such that efficiently. In this method, we will see a different approach. Suppose for all elements , we know the number of inversions contributed by this element , then the inversion count will be equal to the sum of all such contributions for all elements of the array .
Example:
contributes inversion pairs. contributes inversion pairs. contributes inversion pair. contributes inversion pair. contributes inversion pair. Total number of inversions in = .
To implement such kind of method, we need to find the contribution of each element efficiently.
Suppose we have an element and consider an array that stores the positions of all elements that are less than in sorted order. Now, think about how will you find the inversion pairs for this element assuming you are given the array .
Example:
. We want to find the number of inversions for element . . contains positions of all elements in that are smaller than . Now we know that position of is and represent indices of all elements smaller than , so we need to find such number of indexes in the array such that .

To do this, we can use binary search on the array . We know that any element in the array represents the position of elements in that are smaller than . So we just need to find the number of elements in the array that is greater than the position . This means if we find the smallest position in the array such that , then all the elements whose position is , , and so on, will form an inversion pair with the current element .

We do this for all elements in a bottom-up fashion. This means we will calculate the contribution of each element in sorted order. This allows building the array . To calculate the contribution of , we need to guarantee that when we are finding the number of inversions for an element , then the index of all the elements that are smaller than has been inserted into the array . This is why we will consider in sorted order. Now, we will add the contribution of each element to the answer. In this way, we can calculate the inversion count for the given array.
Let us understand this using an example.
Example
, , We will consider elements in increasing order.
Iteration 1: Smallest element = . We will find the position of 4 in the array index using binary search. Now we will insert this index 4 at that position and increment the count of inversions by .
Iteration 2: Next smallest element = . Pos will be 0 as 2 is smaller than 4 in the array index in sorted order. inversions = 1 (This indicates we added the contribution of the inversion (2, 4)).

Iteration 3: Next smallest element = . as 1 is smallest element in index. (Contribution for (1, 2) and (1, 4)).
Iteration 4: Next smallest element =
Iteration 5: Next smallest element = Total number of inversions = 8

This method can be implemented in many ways, one of which is using heap sort and binary search. To simulate the array , we need some kind of data structure that can maintain a sorted order and allows the insertion of new elements. For this, we can use a min-heap as insertion is fast and we can perform a binary search on the heap.
Algorithm
- Create an empty array containing for all elements in .
- Sort .
- Create a min-heap and initialize to 0.
- For each element in :
- Find the position of in the array using binary search.
- Increment by
- Insert into the array index.
Python3 Implementation
Complexity Analysis
Time Complexity
In this method, we use sorting first to sort the elements of array A with their indexes. Now, we iterate over each element and find the contribution of each element using binary search. Iteration over the array takes time and the binary search will take time. So total time complexity = , where N is the number of elements in the input array . Time Complexity:
Space Complexity
In this method, we need extra memory for the heap and to create temporary sort indexes depending upon the elements, so the space complexity is , where N is the number of elements in the input array . Space Complexity:
Conclusion
- We can calculate the inversion count by modifying the merge function in Merge sort. In the merge function, we add the contribution of all such indexes such that and .
- Using heapsort and binary search, we consider each element and add the contribution of to the inversion count. We do this for all elements to find the total number of inversions in an array.