Table of contents
Problem
Given an array of N integers, count the inversion of the array
What is an inversion of an array? Definition: for all i & j < size of array, if i < j then you have to find pair (A[i], A[j]) such that A[j] < A[i].
Brute Force Approach
Find all pairs and count those in which the first element is greater than the second. This can be achieved using two nested for-loops
public class Solution {
public static int numberOfInversions(int []a, int n) {
int pairs = 0;
for(int i=0; i<n; i++){
for(int j=i+1; j<n; j++){
if(a[i]>a[j]) pairs+=1;
}
}
return pairs;
}
}
Optimal Approach (Merge Sort)
We will use merge sort. The root idea is that if we have two sorted arrays, then we can easily find the count of inversions. If arr1[i] > arr2[j]
, then all elements in arr1
(i, i+1, ...)
will form good pairs with arr2[j]
Code
public class Solution {
public static int numberOfInversions(int []a, int n) {
return mergeInversions(a, 0, n-1);
}
private static int mergeInversions(int[] a, int low, int high) {
if (low==high) return 0;
int mid = (low+high)/2;
int leftInversionCount = mergeInversions(a, low,mid);
int rightInversionCount = mergeInversions(a, mid+1, high);
return leftInversionCount+rightInversionCount+mergeInversionCount(a, low, mid, high);
}
private static int mergeInversionCount(int[] arr, int low, int mid, int high) {
int inversionCount = 0;
int ptr1 = low;
int ptr2 = mid+1;
int n = high-low+1;
int dummy[] = new int[n];
int index = 0;
while (ptr1<=mid && ptr2<=high){
if (arr[ptr1]<=arr[ptr2]){
dummy[index] = arr[ptr1];
index+=1;
ptr1+=1;
}else {
dummy[index] = arr[ptr2];
index+=1;
ptr2+=1;
inversionCount+=(mid-ptr1+1);
}
}
while (ptr1<=mid){
dummy[index] = arr[ptr1];
ptr1+=1;
index+=1;
}
while (ptr2<=high){
dummy[index] = arr[ptr2];
ptr2+=1;
index+=1;
}
for (int i=0; i<n; i++){
arr[low+i] = dummy[i];
}
return inversionCount;
}
}