Given an integer array arr[] of size n, find the inversioncount in the array. Two array elements arr[i] and arr[j] form an inversion if arr[i] > arr[j] and i < j.
Note: Inversion Countfor an array indicates that how far (or close) the array is from being sorted. If the array is already sorted, then the inversion count is 0, but if the array is sorted in reverse order, the inversion count is maximum.
[Naive Approach] Using Two Nested Loops - O(n^2) Time and O(1) Space
Traverse through the array, and for every index, find the number of smaller elements on its right side in the array. This can be done using a nested loop. Sum up the inversion counts for all indices in the array and return the sum.
C++
// C++ program to Count Inversions in an array // using nested loop#include<iostream>#include<vector>usingnamespacestd;// Function to count inversions in the arrayintinversionCount(vector<int>&arr){intn=arr.size();intinvCount=0;// Loop through the arrayfor(inti=0;i<n-1;i++){for(intj=i+1;j<n;j++){// If the current element is greater // than the next, increment the countif(arr[i]>arr[j])invCount++;}}returninvCount;}intmain(){vector<int>arr={4,3,2,1};cout<<inversionCount(arr)<<endl;return0;}
C
// C program to Count Inversions in an array // using nested loop#include<stdio.h>// Function to count inversions in the arrayintinversionCount(intarr[],intn){intinvCount=0;for(inti=0;i<n-1;i++){for(intj=i+1;j<n;j++){// If the current element is greater than the next,// increment the countif(arr[i]>arr[j])invCount++;}}returninvCount;}intmain(){intarr[]={4,3,2,1};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",inversionCount(arr,n));return0;}
Java
// Java program to Count Inversions in an array // using nested loopimportjava.util.*;classGfG{// Function to count inversions in the arraystaticintinversionCount(intarr[]){intn=arr.length;intinvCount=0;for(inti=0;i<n-1;i++){for(intj=i+1;j<n;j++){// If the current element is greater than the next,// increment the countif(arr[i]>arr[j])invCount++;}}returninvCount;}publicstaticvoidmain(String[]args){intarr[]={4,3,2,1};System.out.println(inversionCount(arr));}}
Python
# Python program to Count Inversions in an array # using nested loop# Function to count inversions in the arraydefinversionCount(arr):n=len(arr)invCount=0foriinrange(n-1):forjinrange(i+1,n):# If the current element is greater than the next,# increment the countifarr[i]>arr[j]:invCount+=1returninvCountif__name__=="__main__":arr=[4,3,2,1]print(inversionCount(arr))
C#
// C# program to Count Inversions in an array // using nested loopusingSystem;classGfG{// Function to count inversions in the arraystaticintinversionCount(int[]arr){intn=arr.Length;intinvCount=0;for(inti=0;i<n-1;i++){for(intj=i+1;j<n;j++){// If the current element is greater than the next,// increment the countif(arr[i]>arr[j])invCount++;}}returninvCount;}staticvoidMain(){int[]arr={4,3,2,1};Console.WriteLine(inversionCount(arr));}}
JavaScript
// JavaScript program to Count Inversions in an array // using nested loopfunctioninversionCount(arr){letn=arr.length;letinvCount=0;// Loop through the arrayfor(leti=0;i<n-1;i++){for(letj=i+1;j<n;j++){// If the current element is greater than the next,// increment the countif(arr[i]>arr[j]){invCount++;}}}returninvCount;}// driver codeletarr=[4,3,2,1];console.log(inversionCount(arr));
Output
6
[Expected Approach] Using Merge Step of Merge Sort - O(n*log n) Time and O(n) Space
We can use merge sort to count the inversions in an array. First, we divide the array into two halves: left half and right half. Next, we recursively count the inversions in both halves. While merging the two halves back together, we also count how many elements from the left half array are greater than elements from the right half array, as these represent cross inversions (i.e., element from the left halfof the array is greater than an element from the right half during the merging process in the merge sort algorithm). Finally, we sum the inversions from the left half, right half, and the cross inversions to get the total number of inversions in the array. This approach efficiently counts inversions while sorting the array.
Let's understand the above intuition in more detailed form, as we get to know that we have to perform the merge sort on the given array. Below images represents dividing and merging steps of merge sort.
During each merging step of the merge sort algorithm, we count cross inversions by comparing elements from the left half of the array with those from the right half. If we find an element arr[i] in the left half that is greater than an element arr[j] in the right half, we can conclude that all elements after i in the left half will also be greater than arr[j]. This allows us to count multiple inversions at once. Let's suppose if there are k elements remaining in the left half after i, then there are k cross inversions for that particular arr[j]. The rest of the merging process continues as usual, where we combine the two halves into a sorted array. This efficient counting method significantly reduces the number of comparisons needed, enhancing the overall performance of the inversion counting algorithm.
Below Illustration represents the cross inversion of a particular step during the merging process in the merge sort algorithm:
C++
// C++ program to Count Inversions in an array using merge sort#include<iostream>#include<vector>usingnamespacestd;// This function merges two sorted subarrays arr[l..m] and arr[m+1..r] // and also counts inversions in the whole subarray arr[l..r]intcountAndMerge(vector<int>&arr,intl,intm,intr){// Counts in two subarraysintn1=m-l+1,n2=r-m;// Set up two vectors for left and right halvesvector<int>left(n1),right(n2);for(inti=0;i<n1;i++)left[i]=arr[i+l];for(intj=0;j<n2;j++)right[j]=arr[m+1+j];// Initialize inversion count (or result) and merge two halvesintres=0;inti=0,j=0,k=l;while(i<n1&&j<n2){// No increment in inversion count if left[] has a // smaller or equal elementif(left[i]<=right[j])arr[k++]=left[i++];// If right is smaller, then it is smaller than n1-i // elements because left[] is sortedelse{arr[k++]=right[j++];res+=(n1-i);}}// Merge remaining elementswhile(i<n1)arr[k++]=left[i++];while(j<n2)arr[k++]=right[j++];returnres;}// Function to count inversions in the arrayintcountInv(vector<int>&arr,intl,intr){intres=0;if(l<r){intm=(r+l)/2;// Recursively count inversions in the left and // right halvesres+=countInv(arr,l,m);res+=countInv(arr,m+1,r);// Count inversions such that greater element is in // the left half and smaller in the right halfres+=countAndMerge(arr,l,m,r);}returnres;}intinversionCount(vector<int>&arr){intn=arr.size();returncountInv(arr,0,n-1);}intmain(){vector<int>arr={4,3,2,1};cout<<inversionCount(arr);return0;}
C
// C program to Count Inversions in an array using merge sort#include<stdio.h>// This function merges two sorted subarrays arr[l..m] and arr[m+1..r] // and also counts inversions in the whole subarray arr[l..r]intcountAndMerge(intarr[],intl,intm,intr){// Counts in two subarraysintn1=m-l+1,n2=r-m;// Set up two arrays for left and right halvesintleft[n1],right[n2];for(inti=0;i<n1;i++)left[i]=arr[i+l];for(intj=0;j<n2;j++)right[j]=arr[m+1+j];// Initialize inversion count (or result)// and merge two halvesintres=0;inti=0,j=0,k=l;while(i<n1&&j<n2){// No increment in inversion count// if left[] has a smaller or equal elementif(left[i]<=right[j])arr[k++]=left[i++];// If right is smaller, then it is smaller than n1-i // elements because left[] is sortedelse{arr[k++]=right[j++];res+=(n1-i);}}// Merge remaining elementswhile(i<n1)arr[k++]=left[i++];while(j<n2)arr[k++]=right[j++];returnres;}// Function to count inversions in the arrayintcountInv(intarr[],intl,intr){intres=0;if(l<r){intm=(r+l)/2;// Recursively count inversions// in the left and right halvesres+=countInv(arr,l,m);res+=countInv(arr,m+1,r);// Count inversions such that greater element is in // the left half and smaller in the right halfres+=countAndMerge(arr,l,m,r);}returnres;}intinversionCount(intarr[],intn){returncountInv(arr,0,n-1);}intmain(){intarr[]={4,3,2,1};intn=sizeof(arr)/sizeof(arr[0]);printf("%d",inversionCount(arr,n));return0;}
Java
// Java program to Count Inversions in an array using merge sortimportjava.util.*;classGfG{// This function merges two sorted subarrays arr[l..m] and arr[m+1..r] // and also counts inversions in the whole subarray arr[l..r]staticintcountAndMerge(int[]arr,intl,intm,intr){// Counts in two subarraysintn1=m-l+1,n2=r-m;// Set up two arrays for left and right halvesint[]left=newint[n1];int[]right=newint[n2];for(inti=0;i<n1;i++)left[i]=arr[i+l];for(intj=0;j<n2;j++)right[j]=arr[m+1+j];// Initialize inversion count (or result)// and merge two halvesintres=0;inti=0,j=0,k=l;while(i<n1&&j<n2){// No increment in inversion count// if left[] has a smaller or equal elementif(left[i]<=right[j])arr[k++]=left[i++];// If right is smaller, then it is smaller than n1-i // elements because left[] is sortedelse{arr[k++]=right[j++];res+=(n1-i);}}// Merge remaining elementswhile(i<n1)arr[k++]=left[i++];while(j<n2)arr[k++]=right[j++];returnres;}// Function to count inversions in the arraystaticintcountInv(int[]arr,intl,intr){intres=0;if(l<r){intm=(r+l)/2;// Recursively count inversions// in the left and right halvesres+=countInv(arr,l,m);res+=countInv(arr,m+1,r);// Count inversions such that greater element is in // the left half and smaller in the right halfres+=countAndMerge(arr,l,m,r);}returnres;}staticintinversionCount(int[]arr){returncountInv(arr,0,arr.length-1);}publicstaticvoidmain(String[]args){int[]arr={4,3,2,1};System.out.println(inversionCount(arr));}}
Python
# Python program to Count Inversions in an array using merge sort# This function merges two sorted subarrays arr[l..m] and arr[m+1..r] # and also counts inversions in the whole subarray arr[l..r]defcountAndMerge(arr,l,m,r):# Counts in two subarraysn1=m-l+1n2=r-m# Set up two lists for left and right halvesleft=arr[l:m+1]right=arr[m+1:r+1]# Initialize inversion count (or result)# and merge two halvesres=0i=0j=0k=lwhilei<n1andj<n2:# No increment in inversion count# if left[] has a smaller or equal elementifleft[i]<=right[j]:arr[k]=left[i]i+=1else:arr[k]=right[j]j+=1res+=(n1-i)k+=1# Merge remaining elementswhilei<n1:arr[k]=left[i]i+=1k+=1whilej<n2:arr[k]=right[j]j+=1k+=1returnres# Function to count inversions in the arraydefcountInv(arr,l,r):res=0ifl<r:m=(r+l)//2# Recursively count inversions# in the left and right halvesres+=countInv(arr,l,m)res+=countInv(arr,m+1,r)# Count inversions such that greater element is in # the left half and smaller in the right halfres+=countAndMerge(arr,l,m,r)returnresdefinversionCount(arr):returncountInv(arr,0,len(arr)-1)if__name__=="__main__":arr=[4,3,2,1]print(inversionCount(arr))
C#
// C# program to Count Inversions in an array using merge sortusingSystem;usingSystem.Collections.Generic;classGfG{// This function merges two sorted subarrays arr[l..m] and arr[m+1..r] // and also counts inversions in the whole subarray arr[l..r]staticintcountAndMerge(int[]arr,intl,intm,intr){// Counts in two subarraysintn1=m-l+1,n2=r-m;// Set up two arrays for left and right halvesint[]left=newint[n1];int[]right=newint[n2];for(intx=0;x<n1;x++)left[x]=arr[x+l];for(intx=0;x<n2;x++)right[x]=arr[m+1+x];// Initialize inversion count (or result)// and merge two halvesintres=0;inti=0,j=0,k=l;while(i<n1&&j<n2){// No increment in inversion count// if left[] has a smaller or equal elementif(left[i]<=right[j])arr[k++]=left[i++];else{arr[k++]=right[j++];res+=(n1-i);}}// Merge remaining elementswhile(i<n1)arr[k++]=left[i++];while(j<n2)arr[k++]=right[j++];returnres;}// Function to count inversions in the arraystaticintcountInv(int[]arr,intl,intr){intres=0;if(l<r){intm=(r+l)/2;// Recursively count inversions// in the left and right halvesres+=countInv(arr,l,m);res+=countInv(arr,m+1,r);// Count inversions such that greater element is in // the left half and smaller in the right halfres+=countAndMerge(arr,l,m,r);}returnres;}staticintinversionCount(int[]arr){returncountInv(arr,0,arr.Length-1);}staticvoidMain(){int[]arr={4,3,2,1};Console.WriteLine(inversionCount(arr));}}
JavaScript
// JavaScript program to Count Inversions in an array using merge sort// This function merges two sorted subarrays arr[l..m] and arr[m+1..r] // and also counts inversions in the whole subarray arr[l..r]functioncountAndMerge(arr,l,m,r){// Counts in two subarraysletn1=m-l+1,n2=r-m;// Set up two arrays for left and right halvesletleft=arr.slice(l,m+1);letright=arr.slice(m+1,r+1);// Initialize inversion count (or result)// and merge two halvesletres=0;leti=0,j=0,k=l;while(i<n1&&j<n2){// No increment in inversion count// if left[] has a smaller or equal elementif(left[i]<=right[j])arr[k++]=left[i++];else{arr[k++]=right[j++];res+=(n1-i);}}// Merge remaining elementswhile(i<n1)arr[k++]=left[i++];while(j<n2)arr[k++]=right[j++];returnres;}// Function to count inversions in the arrayfunctioncountInv(arr,l,r){letres=0;if(l<r){letm=Math.floor((r+l)/2);// Recursively count inversions// in the left and right halvesres+=countInv(arr,l,m);res+=countInv(arr,m+1,r);// Count inversions such that greater element is in // the left half and smaller in the right halfres+=countAndMerge(arr,l,m,r);}returnres;}functioninversionCount(arr){returncountInv(arr,0,arr.length-1);}// Driver Codeletarr=[4,3,2,1];console.log(inversionCount(arr));
Output
6
Note: The above code modifies (or sorts) the input array. If we want to count only inversions, we need to create a copy of the original array and perform operation on the copy array.
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.