Inversion Count for an array indicates – how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum.
Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j
Example:
Input: arr[] = {8, 4, 2, 1}
Output: 6
Explanation: Given array has six inversions:
(8, 4), (4, 2), (8, 2), (8, 1), (4, 1), (2, 1).
Input: arr[] = {3, 1, 2}
Output: 2
Explanation: Given array has two inversions:
(3, 1), (3, 2)
METHOD 1 (Simple)
- Approach :Traverse through the array and for every index find the number of smaller elements on its right side of the array. This can be done using a nested loop. Sum up the counts for all index in the array and print the sum.
- Algorithm :
- Traverse through the array from start to end
- For every element find the count of elements smaller than the current number upto that index using another loop.
- Sum up the count of inversion for every index.
- Print the count of inversions.
-
Implementation:
C++
// C++ program to Count Inversions// in an array#include <bits/stdc++.h>usingnamespacestd;intgetInvCount(intarr[],intn){intinv_count = 0;for(inti = 0; i < n - 1; i++)for(intj = i + 1; j < n; j++)if(arr[i] > arr[j])inv_count++;returninv_count;}// Driver Codeintmain(){intarr[] = { 1, 20, 6, 4, 5 };intn =sizeof(arr) /sizeof(arr[0]);cout <<" Number of inversions are "<< getInvCount(arr, n);return0;}// This code is contributed// by Akanksha Raichevron_rightfilter_noneC
// C program to Count// Inversions in an array#include <stdio.h>#include <stdlib.h>intgetInvCount(intarr[],intn){intinv_count = 0;for(inti = 0; i < n - 1; i++)for(intj = i + 1; j < n; j++)if(arr[i] > arr[j])inv_count++;returninv_count;}/* Driver program to test above functions */intmain(){intarr[] = { 1, 20, 6, 4, 5 };intn =sizeof(arr) /sizeof(arr[0]);printf(" Number of inversions are %d \n", getInvCount(arr, n));return0;}chevron_rightfilter_noneJava
// Java program to count// inversions in an arrayclassTest {staticintarr[] =newint[] {1,20,6,4,5};staticintgetInvCount(intn){intinv_count =0;for(inti =0; i < n -1; i++)for(intj = i +1; j < n; j++)if(arr[i] > arr[j])inv_count++;returninv_count;}// Driver method to test the above functionpublicstaticvoidmain(String[] args){System.out.println("Number of inversions are "+ getInvCount(arr.length));}}chevron_rightfilter_nonePython3
# Python3 program to count# inversions in an arraydefgetInvCount(arr, n):inv_count=0foriinrange(n):forjinrange(i+1, n):if(arr[i] > arr[j]):inv_count+=1returninv_count# Driver Codearr=[1,20,6,4,5]n=len(arr)print("Number of inversions are",getInvCount(arr, n))# This code is contributed by Smitha Dinesh Semwalchevron_rightfilter_noneC#
// C# program to count inversions// in an arrayusingSystem;usingSystem.Collections.Generic;classGFG {staticint[] arr =newint[] { 1, 20, 6, 4, 5 };staticintgetInvCount(intn){intinv_count = 0;for(inti = 0; i < n - 1; i++)for(intj = i + 1; j < n; j++)if(arr[i] > arr[j])inv_count++;returninv_count;}// Driver codepublicstaticvoidMain(){Console.WriteLine("Number of "+"inversions are "+ getInvCount(arr.Length));}}// This code is contributed by Sam007chevron_rightfilter_nonePHP
<?php// PHP program to Count Inversions// in an arrayfunctiongetInvCount(&$arr,$n){$inv_count= 0;for($i= 0;$i<$n- 1;$i++)for($j=$i+ 1;$j<$n;$j++)if($arr[$i] >$arr[$j])$inv_count++;return$inv_count;}// Driver Code$arr=array(1, 20, 6, 4, 5 );$n= sizeof($arr);echo"Number of inversions are ",getInvCount($arr,$n);// This code is contributed by ita_c?>chevron_rightfilter_none
Output:
Number of inversions are 5
- Complexity Analysis:
- Time Complexity: O(n^2), Two nested loops are needed to traverse the array from start to end so the Time complexity is O(n^2)
- Space Compelxity:O(1), No extra space is required.
METHOD 2(Enhance Merge Sort)
- Approach:
Suppose the number of inversions in the left half and right half of the array (let be inv1 and inv2), what kinds of inversions are not accounted for in Inv1 + Inv2? The answer is – the inversions that need to be counted during the merge step. Therefore, to get a number of inversions, that needs to be added a number of inversions in the left subarray, right subarray and merge().
How to get number of inversions in merge()?
In merge process, let i is used for indexing left sub-array and j for right sub-array. At any step in merge(), if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j]
The complete picture:

- Algorithm:
- The idea is similar to merge sort, divide the array into two equal or almost equal halves in each step until the base case is reached.
- Create a function merge that counts the number of inversions when two halves of the array are merged, create two indices i and j, i is the index for first half and j is an index of the second half. if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j].
- Create a recursive function to divide the array into halves and find the answer by summing the number of inversions is the first half, number of inversion in the second half and the number of inversions by merging the two.
- The base case of recursion is when there is only one element in the given half.
- Print the answer
-
Implementation:
C++
// C++ program to Count// Inversions in an array// using Merge Sort#include <bits/stdc++.h>usingnamespacestd;int_mergeSort(intarr[],inttemp[],intleft,intright);intmerge(intarr[],inttemp[],intleft,intmid,intright);/* This function sorts the input array and returns thenumber of inversions in the array */intmergeSort(intarr[],intarray_size){inttemp[array_size];return_mergeSort(arr, temp, 0, array_size - 1);}/* An auxiliary recursive function that sorts the input array andreturns the number of inversions in the array. */int_mergeSort(intarr[],inttemp[],intleft,intright){intmid, inv_count = 0;if(right > left) {/* Divide the array into two parts andcall _mergeSortAndCountInv()for each of the parts */mid = (right + left) / 2;/* Inversion count will be sum ofinversions in left-part, right-partand number of inversions in merging */inv_count += _mergeSort(arr, temp, left, mid);inv_count += _mergeSort(arr, temp, mid + 1, right);/*Merge the two parts*/inv_count += merge(arr, temp, left, mid + 1, right);}returninv_count;}/* This funt merges two sorted arraysand returns inversion count in the arrays.*/intmerge(intarr[],inttemp[],intleft,intmid,intright){inti, j, k;intinv_count = 0;i = left;/* i is index for left subarray*/j = mid;/* j is index for right subarray*/k = left;/* k is index for resultant merged subarray*/while((i <= mid - 1) && (j <= right)) {if(arr[i] <= arr[j]) {temp[k++] = arr[i++];}else{temp[k++] = arr[j++];/* this is tricky -- see aboveexplanation/diagram for merge()*/inv_count = inv_count + (mid - i);}}/* Copy the remaining elements of left subarray(if there are any) to temp*/while(i <= mid - 1)temp[k++] = arr[i++];/* Copy the remaining elements of right subarray(if there are any) to temp*/while(j <= right)temp[k++] = arr[j++];/*Copy back the merged elements to original array*/for(i = left; i <= right; i++)arr[i] = temp[i];returninv_count;}// Driver codeintmain(){intarr[] = { 1, 20, 6, 4, 5 };intn =sizeof(arr) /sizeof(arr[0]);intans = mergeSort(arr, n);cout <<" Number of inversions are "<< ans;return0;}// This is code is contributed by rathbhupendrachevron_rightfilter_noneC
// C program to Count// Inversions in an array// using Merge Sort#include <stdio.h>#include <stdlib.h>int_mergeSort(intarr[],inttemp[],intleft,intright);intmerge(intarr[],inttemp[],intleft,intmid,intright);/* This function sorts the input array and returns thenumber of inversions in the array */intmergeSort(intarr[],intarray_size){int* temp = (int*)malloc(sizeof(int) * array_size);return_mergeSort(arr, temp, 0, array_size - 1);}/* An auxiliary recursive function that sorts the input array andreturns the number of inversions in the array. */int_mergeSort(intarr[],inttemp[],intleft,intright){intmid, inv_count = 0;if(right > left) {/* Divide the array into two parts and call _mergeSortAndCountInv()for each of the parts */mid = (right + left) / 2;/* Inversion count will be the sum of inversions in left-part, right-partand number of inversions in merging */inv_count += _mergeSort(arr, temp, left, mid);inv_count += _mergeSort(arr, temp, mid + 1, right);/*Merge the two parts*/inv_count += merge(arr, temp, left, mid + 1, right);}returninv_count;}/* This funt merges two sorted arrays and returns inversion count inthe arrays.*/intmerge(intarr[],inttemp[],intleft,intmid,intright){inti, j, k;intinv_count = 0;i = left;/* i is index for left subarray*/j = mid;/* j is index for right subarray*/k = left;/* k is index for resultant merged subarray*/while((i <= mid - 1) && (j <= right)) {if(arr[i] <= arr[j]) {temp[k++] = arr[i++];}else{temp[k++] = arr[j++];/*this is tricky -- see above explanation/diagram for merge()*/inv_count = inv_count + (mid - i);}}/* Copy the remaining elements of left subarray(if there are any) to temp*/while(i <= mid - 1)temp[k++] = arr[i++];/* Copy the remaining elements of right subarray(if there are any) to temp*/while(j <= right)temp[k++] = arr[j++];/*Copy back the merged elements to original array*/for(i = left; i <= right; i++)arr[i] = temp[i];returninv_count;}/* Driver program to test above functions */intmain(intargv,char** args){intarr[] = { 1, 20, 6, 4, 5 };printf(" Number of inversions are %d \n", mergeSort(arr, 5));getchar();return0;}chevron_rightfilter_noneJava
// Java implementation of the approachimportjava.util.Arrays;publicclassGFG {// Function to count the number of inversions// during the merge processprivatestaticintmergeAndCount(int[] arr,intl,intm,intr){// Left subarrayint[] left = Arrays.copyOfRange(arr, l, m +1);// Right subarrayint[] right = Arrays.copyOfRange(arr, m +1, r +1);inti =0, j =0, k = l, swaps =0;while(i < left.length && j < right.length) {if(left[i] <= right[j])arr[k++] = left[i++];else{arr[k++] = right[j++];swaps += (m +1) - (l + i);}}returnswaps;}// Merge sort functionprivatestaticintmergeSortAndCount(int[] arr,intl,intr){// Keeps track of the inversion count at a// particular node of the recursion treeintcount =0;if(l < r) {intm = (l + r) /2;// Total inversion count = left subarray count// + right subarray count + merge count// Left subarray countcount += mergeSortAndCount(arr, l, m);// Right subarray countcount += mergeSortAndCount(arr, m +1, r);// Merge countcount += mergeAndCount(arr, l, m, r);}returncount;}// Driver codepublicstaticvoidmain(String[] args){int[] arr = {1,20,6,4,5};System.out.println(mergeSortAndCount(arr,0, arr.length -1));}}// This code is contributed by Pradip Basakchevron_rightfilter_nonePython3
# Python 3 program to count inversions in an array# Function to Use Inversion CountdefmergeSort(arr, n):# A temp_arr is created to store# sorted array in merge functiontemp_arr=[0]*nreturn_mergeSort(arr, temp_arr,0, n-1)# This Function will use MergeSort to count inversionsdef_mergeSort(arr, temp_arr, left, right):# A variable inv_count is used to store# inversion counts in each recursive callinv_count=0# We will make a recursive call if and only if# we have more than one elementsifleft < right:# mid is calculated to divide the array into two subarrays# Floor division is must in case of pythonmid=(left+right)//2# It will calculate inversion counts in the left subarrayinv_count+=_mergeSort(arr, temp_arr, left, mid)# It will calculate inversion counts in right subarrayinv_count+=_mergeSort(arr, temp_arr, mid+1, right)# It will merge two subarrays in a sorted subarrayinv_count+=merge(arr, temp_arr, left, mid, right)returninv_count# This function will merge two subarrays in a single sorted subarraydefmerge(arr, temp_arr, left, mid, right):i=left# Starting index of left subarrayj=mid+1# Starting index of right subarrayk=left# Starting index of to be sorted subarrayinv_count=0# Conditions are checked to make sure that i and j don't exceed their# subarray limits.whilei <=midandj <=right:# There will be no inversion if arr[i] <= arr[j]ifarr[i] <=arr[j]:temp_arr[k]=arr[i]k+=1i+=1else:# Inversion will occur.temp_arr[k]=arr[j]inv_count+=(mid-i+1)k+=1j+=1# Copy the remaining elements of left subarray into temporary arraywhilei <=mid:temp_arr[k]=arr[i]k+=1i+=1# Copy the remaining elements of right subarray into temporary arraywhilej <=right:temp_arr[k]=arr[j]k+=1j+=1# Copy the sorted subarray into Original arrayforloop_varinrange(left, right+1):arr[loop_var]=temp_arr[loop_var]returninv_count# Driver Code# Given array isarr=[1,20,6,4,5]n=len(arr)result=mergeSort(arr, n)print("Number of inversions are", result)# This code is contributed by ankush_953chevron_rightfilter_noneC#
// C# implementation of counting the// inversion using merge sortusingSystem;publicclassTest {/* This method sorts the input array and returns thenumber of inversions in the array */staticintmergeSort(int[] arr,intarray_size){int[] temp =newint[array_size];return_mergeSort(arr, temp, 0, array_size - 1);}/* An auxiliary recursive method that sorts the input array andreturns the number of inversions in the array. */staticint_mergeSort(int[] arr,int[] temp,intleft,intright){intmid, inv_count = 0;if(right > left) {/* Divide the array into two parts and call _mergeSortAndCountInv()for each of the parts */mid = (right + left) / 2;/* Inversion count will be the sum of inversions in left-part, right-partand number of inversions in merging */inv_count += _mergeSort(arr, temp, left, mid);inv_count += _mergeSort(arr, temp, mid + 1, right);/*Merge the two parts*/inv_count += merge(arr, temp, left, mid + 1, right);}returninv_count;}/* This method merges two sorted arrays and returns inversion count inthe arrays.*/staticintmerge(int[] arr,int[] temp,intleft,intmid,intright){inti, j, k;intinv_count = 0;i = left;/* i is index for left subarray*/j = mid;/* j is index for right subarray*/k = left;/* k is index for resultant merged subarray*/while((i <= mid - 1) && (j <= right)) {if(arr[i] <= arr[j]) {temp[k++] = arr[i++];}else{temp[k++] = arr[j++];/*this is tricky -- see above explanation/diagram for merge()*/inv_count = inv_count + (mid - i);}}/* Copy the remaining elements of left subarray(if there are any) to temp*/while(i <= mid - 1)temp[k++] = arr[i++];/* Copy the remaining elements of right subarray(if there are any) to temp*/while(j <= right)temp[k++] = arr[j++];/*Copy back the merged elements to original array*/for(i = left; i <= right; i++)arr[i] = temp[i];returninv_count;}// Driver method to test the above functionpublicstaticvoidMain(){int[] arr =newint[] { 1, 20, 6, 4, 5 };Console.Write("Number of inversions are "+ mergeSort(arr, 5));}}// This code is contributed by Rajput-Jichevron_rightfilter_none
Output:Number of inversions are 5
- Complexity Analysis:
- Time Complexity: O(n log n), The algorithm used is divide and conquer, So in each level one full array traversal is needed and there are log n levels so the time complexity is O(n log n).
- Space Compelxity: O(n), Temporary array.
Note that above code modifies (or sorts) the input array. If we want to count only inversions then we need to create a copy of original array and call mergeSort() on copy.
You may like to see.
Count inversions in an array | Set 2 (Using Self-Balancing BST)
Counting Inversions using Set in C++ STL
Count inversions in an array | Set 3 (Using BIT)
References:
http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08-inversions.pdf
http://www.cp.eng.chula.ac.th/~piak/teaching/algo/algo2008/count-inv.htm
Please write comments if you find any bug in the above program/algorithm or other ways to solve the same problem.
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.
Recommended Posts:
- Count inversions in an array | Set 2 (Using Self-Balancing BST)
- Count inversions in an array | Set 3 (Using BIT)
- Count inversions in an array | Set 4 ( Using Trie )
- Merge Sort with O(1) extra space merge and O(n lg n) time
- Count of smaller elements on right side of each element in an Array using Merge sort
- Count of distinct numbers in an Array in a range for Online Queries using Merge Sort Tree
- Time complexity of insertion sort when there are O(n) inversions?
- Why Quick Sort preferred for Arrays and Merge Sort for Linked Lists?
- Quick Sort vs Merge Sort
- Merge Sort vs. Insertion Sort
- Merge operations using STL in C++ | merge(), includes(), set_union(), set_intersection(), set_difference(), ., inplace_merge,
- Count Inversions of size three in a given array
- Count inversions of size k in a given array
- Check if the count of inversions of two given types on an Array are equal or not
- Counting Inversions using Set in C++ STL
- Counting Inversions using Ordered Set and GNU C++ PBDS
- Counting inversions in an array using segment tree
- Union and Intersection of two linked lists | Set-2 (Using Merge Sort)
- Significant Inversions in an Array
- Comparison among Bubble Sort, Selection Sort and Insertion Sort

