Pre-requisite: Policy based data structure Given an array arr[], the task is to find the number of inversions for each element of the array.
Inversion Count: for an array indicates – how far (or close) the array is from being sorted. If the array is already sorted then the inversion count is 0. If the array is sorted in the reverse order then the inversion count is the maximum. Formally, Number of indices
and
such that
and
.
Examples:
Input: {5, 2, 3, 2, 3, 8, 1} Output: {0, 1, 1, 2, 1, 0, 6} Explanation: Inversion count for each elements – Element at index 0: There are no elements with less index than 0, which is greater than arr[0]. Element at index 1: There is one element with less index than 1, which is greater than 2. That is 5. Element at index 2: There is one element with less index than 2, which is greater than 3. That is 5. Element at index 3: There are two elements with less index than 3, which is greater than 2. That is 5, 3. Element at index 4: There is one element with less index than 4, which is greater than 3. That is 5. Element at index 5: There are no elements with less index than 5, which is greater than 8. Element at index 6: There are six elements with less index than 6, which is greater than 1. That is 5, 2, 3, 2, 3 Input: arr[] = {3, 2, 1} Output: {0, 1, 2}
Approach:
- Create a policy based data structure of type pair.
- Iterate the given array and perform the following steps –
- Apply order_of_key({X, N+1}) for each element X where N is the size of array. Note: order_of_key is nothing but lower_bound. Also, we used N+1 because it is greater than all the indices in the array.
- Let order_of_key comes out to be l, then the inversion count for current element will be equal to
which is ultimately the count of elements smaller than X and came before X in the array.
- Insert the current element X along with its index in the policy-based data structure St. The index is inserted along with each element for its unique identification in the set and to deal with duplicates.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef tree<pair< int , int >, null_type,
less<pair< int , int > >, rb_tree_tag,
tree_order_statistics_node_update>
new_data_set;
void inversionCount( int arr[], int n)
{
int ans[n];
new_data_set St;
for ( int i = 0; i < n; i++) {
int cur = St.order_of_key({ arr[i],
n + 1 });
ans[i] = St.size() - cur;
St.insert({ arr[i], i });
}
for ( int i = 0; i < n; i++) {
cout << ans[i] << " " ;
}
cout << "\n" ;
}
int main()
{
int arr[] = { 5, 2, 3, 2, 3, 8, 1 };
int n = sizeof (arr) / sizeof ( int );
inversionCount(arr, n);
return 0;
}
|
Java
import java.util.*;
import java.io.*;
import java.lang.*;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;
import java.util.TreeSet;
public class GFG
{
public static void inversionCount( int [] arr, int n)
{
int [] ans = new int [n];
TreeSet<Entry<Integer, Integer>> St = new TreeSet<>( new Comparator<Entry<Integer, Integer>>() {
@Override
public int compare(Entry<Integer, Integer> a, Entry<Integer, Integer> b) {
return a.getKey().compareTo(b.getKey());
}
});
for ( int i = 0 ; i < n; i++) {
int cur = St.headSet( new SimpleEntry<Integer, Integer>(arr[i], n+ 1 )).size();
ans[i] = St.size() - cur;
St.add( new SimpleEntry<Integer, Integer>(arr[i], i));
}
for ( int i = 0 ; i < n; i++) {
System.out.print(ans[i] + " " );
}
System.out.print( "\n" );
}
public static void main(String[] args) {
int [] arr = { 5 , 2 , 3 , 2 , 3 , 8 , 1 };
int n = arr.length;
inversionCount(arr, n);
}
}
|
Python3
from collections import defaultdict
from bisect import bisect_right
def inversionCount(arr, n):
ans = [ 0 ] * n
index_dict = defaultdict( list )
for i in range (n):
cur = bisect_right(index_dict[arr[i]], i)
ans[i] = i - cur
index_dict[arr[i]].append(i)
for i in range (n):
print (ans[i], end = ' ' )
print ()
if __name__ = = '__main__' :
arr = [ 5 , 2 , 3 , 2 , 3 , 8 , 1 ]
n = len (arr)
inversionCount(arr, n)
|
Javascript
function inversionCount(arr, n) {
let ans = new Array(n).fill(0);
let index_dict = {};
for (let i = 0; i < n; i++) {
if (arr[i] in index_dict) {
let cur = index_dict[arr[i]].filter((index) => index < i).length;
ans[i] = i - cur;
} else {
ans[i] = i;
}
if (arr[i] in index_dict) {
index_dict[arr[i]].push(i);
} else {
index_dict[arr[i]] = [i];
}
}
console.log(ans.join(' '));
}
let arr = [5, 2, 3, 2, 3, 8, 1];
let n = arr.length;
inversionCount(arr, n);
|
Time Complexity: 
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
20 Feb, 2023
Like Article
Save Article