# Significant Inversions in an Array

Given an array arr[], the task is to finds the total significant inversion count for the array. Two elements arr[i] and arr[j] form a significant inversion if arr[i] > 2 * arr[j] and i < j.

Examples:

Input: arr[] = { 1, 20, 6, 4, 5 }
Output: 3
Significant inversion pair are (20, 6), (20, 5) and (20, 4).

Input: arr[] = { 1, 20 }
Output: 0

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Prerequisite: Counting Inversions

Approach:

• The basic idea to find inversions will be based on the above prerequisite, using the Divide and Conquer approach of the modified merge sort.
• The number of significant inversions in the left half and the right half can be counted. Including the count of significant inversion with index (i, j) such that i is in the left half and j is in the right half and then add all three to get the total significant inversion count.
• Approach used in the above link can be modified to perform two passes of left and right half during merge step. In first pass, calculate the number of significant inversion count in the merged array. For any index i in left array if arr[i] > 2 * arr[j], then all the elements to the left of ith index in left array will also contribute to significant inversion count. Increment j. Otherwise increment i.
• Second pass will be to construct the merged array. Here two passes are required because in the normal inversion count, the two passes would move i and j at the same points so can be combined, but that is not true in this case.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach ` `#include ` `using` `namespace` `std; ` ` `  `int` `_mergeSort(``int` `arr[], ``int` `temp[], ``int` `left, ``int` `right); ` `int` `merge(``int` `arr[], ``int` `temp[], ``int` `left, ``int` `mid, ``int` `right); ` ` `  `// Function that sorts the input array ` `// and returns the number of inversions ` `// in the array ` `int` `mergeSort(``int` `arr[], ``int` `array_size) ` `{ ` `    ``int` `temp[array_size]; ` `    ``return` `_mergeSort(arr, temp, 0, array_size - 1); ` `} ` ` `  `// Recursive function that sorts the input ` `// array and returns the number of ` `// inversions in the array ` `int` `_mergeSort(``int` `arr[], ``int` `temp[], ``int` `left, ``int` `right) ` `{ ` `    ``int` `mid, 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 sum of the ` `        ``// inversions in the left-part, the right-part ` `        ``// and the 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); ` `    ``} ` `    ``return` `inv_count; ` `} ` ` `  `// Function that merges the two sorted arrays ` `// and returns the inversion count in the arrays ` `int` `merge(``int` `arr[], ``int` `temp[], ``int` `left, ` `          ``int` `mid, ``int` `right) ` `{ ` `    ``int` `i, j, k; ` `    ``int` `inv_count = 0; ` ` `  `    ``// i is the index for the left subarray ` `    ``i = left; ` ` `  `    ``// j is the index for the right subarray ` `    ``j = mid; ` ` `  `    ``// k is the index for the resultant ` `    ``// merged subarray ` `    ``k = left; ` ` `  `    ``// First pass to count number ` `    ``// of significant inversions ` `    ``while` `((i <= mid - 1) && (j <= right)) { ` `        ``if` `(arr[i] > 2 * arr[j]) { ` `            ``inv_count += (mid - i); ` `            ``j++; ` `        ``} ` `        ``else` `{ ` `            ``i++; ` `        ``} ` `    ``} ` ` `  `    ``// i is the index for the left subarray ` `    ``i = left; ` ` `  `    ``// j is the index for the right subarray ` `    ``j = mid; ` ` `  `    ``// k is the index for the resultant ` `    ``// merged subarray ` `    ``k = left; ` ` `  `    ``// Second pass to merge the two sorted arrays ` `    ``while` `((i <= mid - 1) && (j <= right)) { ` `        ``if` `(arr[i] <= arr[j]) { ` `            ``temp[k++] = arr[i++]; ` `        ``} ` `        ``else` `{ ` `            ``temp[k++] = arr[j++]; ` `        ``} ` `    ``} ` ` `  `    ``// Copy the remaining elements of the left ` `    ``// subarray (if there are any) to temp ` `    ``while` `(i <= mid - 1) ` `        ``temp[k++] = arr[i++]; ` ` `  `    ``// Copy the remaining elements of the right ` `    ``// subarray (if there are any) to temp ` `    ``while` `(j <= right) ` `        ``temp[k++] = arr[j++]; ` ` `  `    ``// Copy back the merged elements to ` `    ``// the original array ` `    ``for` `(i = left; i <= right; i++) ` `        ``arr[i] = temp[i]; ` ` `  `    ``return` `inv_count; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``int` `arr[] = { 1, 20, 6, 4, 5 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]); ` ` `  `    ``cout << mergeSort(arr, n); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java implementation of the above approach  ` `class` `GFG  ` `{ ` `         `  `    ``// Function that sorts the input array  ` `    ``// and returns the number of inversions  ` `    ``// in the array  ` `    ``static` `int` `mergeSort(``int` `arr[], ``int` `array_size)  ` `    ``{  ` `        ``int` `temp[] = ``new` `int``[array_size];  ` `        ``return` `_mergeSort(arr, temp, ``0``, array_size - ``1``);  ` `    ``}  ` `     `  `    ``// Recursive function that sorts the input  ` `    ``// array and returns the number of  ` `    ``// inversions in the array  ` `    ``static` `int` `_mergeSort(``int` `arr[], ``int` `temp[], ` `                          ``int` `left, ``int` `right)  ` `    ``{  ` `        ``int` `mid, 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 sum of the  ` `            ``// inversions in the left-part, the right-part  ` `            ``// and the 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);  ` `        ``}  ` `        ``return` `inv_count;  ` `    ``}  ` `     `  `    ``// Function that merges the two sorted arrays  ` `    ``// and returns the inversion count in the arrays  ` `    ``static` `int` `merge(``int` `arr[], ``int` `temp[], ``int` `left,  ` `                                ``int` `mid, ``int` `right)  ` `    ``{  ` `        ``int` `i, j, k;  ` `        ``int` `inv_count = ``0``;  ` `     `  `        ``// i is the index for the left subarray  ` `        ``i = left;  ` `     `  `        ``// j is the index for the right subarray  ` `        ``j = mid;  ` `     `  `        ``// k is the index for the resultant  ` `        ``// merged subarray  ` `        ``k = left;  ` `     `  `        ``// First pass to count number  ` `        ``// of significant inversions  ` `        ``while` `((i <= mid - ``1``) && (j <= right))  ` `        ``{  ` `            ``if` `(arr[i] > ``2` `* arr[j])  ` `            ``{  ` `                ``inv_count += (mid - i);  ` `                ``j++;  ` `            ``}  ` `            ``else`  `            ``{  ` `                ``i++;  ` `            ``}  ` `        ``}  ` `     `  `        ``// i is the index for the left subarray  ` `        ``i = left;  ` `     `  `        ``// j is the index for the right subarray  ` `        ``j = mid;  ` `     `  `        ``// k is the index for the resultant  ` `        ``// merged subarray  ` `        ``k = left;  ` `     `  `        ``// Second pass to merge the two sorted arrays  ` `        ``while` `((i <= mid - ``1``) && (j <= right)) ` `        ``{  ` `            ``if` `(arr[i] <= arr[j])  ` `            ``{  ` `                ``temp[k++] = arr[i++];  ` `            ``}  ` `            ``else`  `            ``{  ` `                ``temp[k++] = arr[j++];  ` `            ``}  ` `        ``}  ` `     `  `        ``// Copy the remaining elements of the left  ` `        ``// subarray (if there are any) to temp  ` `        ``while` `(i <= mid - ``1``)  ` `            ``temp[k++] = arr[i++];  ` `     `  `        ``// Copy the remaining elements of the right  ` `        ``// subarray (if there are any) to temp  ` `        ``while` `(j <= right)  ` `            ``temp[k++] = arr[j++];  ` `     `  `        ``// Copy back the merged elements to  ` `        ``// the original array  ` `        ``for` `(i = left; i <= right; i++)  ` `            ``arr[i] = temp[i];  ` `     `  `        ``return` `inv_count;  ` `    ``}  ` `     `  `    ``// Driver code  ` `    ``public` `static` `void` `main (String[] args)  ` `    ``{  ` `        ``int` `arr[] = { ``1``, ``20``, ``6``, ``4``, ``5` `};  ` `        ``int` `n = arr.length;  ` `     `  `        ``System.out.println(mergeSort(arr, n));  ` `    ``}  ` `} ` ` `  `// This code is contributed by AnkitRai01 `

## Python3

 `# Python3 implementation of the approach ` ` `  `# Function that sorts the input array ` `# and returns the number of inversions ` `# in the array ` `def` `mergeSort(arr, array_size): ` `    ``temp ``=` `[``0` `for` `i ``in` `range``(array_size)] ` `    ``return` `_mergeSort(arr, temp, ``0``,  ` `                      ``array_size ``-` `1``) ` ` `  `# Recursive function that sorts the input ` `# array and returns the number of ` `# inversions in the array ` `def` `_mergeSort(arr, temp, left, right): ` `    ``mid, inv_count ``=` `0``, ``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 sum of the ` `        ``# inversions in the left-part, the right-part ` `        ``# and the 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) ` `    ``return` `inv_count ` ` `  `# Function that merges the two sorted arrays ` `# and returns the inversion count in the arrays ` `def` `merge(arr, temp, left,mid, right): ` `    ``inv_count ``=` `0` ` `  `    ``# i is the index for the left subarray ` `    ``i ``=` `left ` ` `  `    ``# j is the index for the right subarray ` `    ``j ``=` `mid ` ` `  `    ``# k is the index for the resultant ` `    ``# merged subarray ` `    ``k ``=` `left ` ` `  `    ``# First pass to count number ` `    ``# of significant inversions ` `    ``while` `((i <``=` `mid ``-` `1``) ``and` `(j <``=` `right)): ` `        ``if` `(arr[i] > ``2` `*` `arr[j]): ` `            ``inv_count ``+``=` `(mid ``-` `i) ` `            ``j ``+``=` `1` `        ``else``: ` `            ``i ``+``=` `1` ` `  `    ``# i is the index for the left subarray ` `    ``i ``=` `left ` ` `  `    ``# j is the index for the right subarray ` `    ``j ``=` `mid ` ` `  `    ``# k is the index for the resultant ` `    ``# merged subarray ` `    ``k ``=` `left ` ` `  `    ``# Second pass to merge the two sorted arrays ` `    ``while` `((i <``=` `mid ``-` `1``) ``and` `(j <``=` `right)): ` `        ``if` `(arr[i] <``=` `arr[j]): ` `            ``temp[k] ``=` `arr[i] ` `            ``i, k ``=` `i ``+` `1``, k ``+` `1` `        ``else``: ` `            ``temp[k] ``=` `arr[j] ` `            ``k, j ``=` `k ``+` `1``, j ``+` `1` ` `  `    ``# Copy the remaining elements of the left ` `    ``# subarray (if there are any) to temp ` `    ``while` `(i <``=` `mid ``-` `1``): ` `        ``temp[k] ``=` `arr[i] ` `        ``i, k ``=` `i ``+` `1``, k ``+` `1` ` `  `    ``# Copy the remaining elements of the right ` `    ``# subarray (if there are any) to temp ` `    ``while` `(j <``=` `right): ` `        ``temp[k] ``=` `arr[j] ` `        ``j, k ``=` `j ``+` `1``, k ``+` `1` ` `  `    ``# Copy back the merged elements to ` `    ``# the original array ` `    ``for` `i ``in` `range``(left, right ``+` `1``): ` `        ``arr[i] ``=` `temp[i] ` ` `  `    ``return` `inv_count ` ` `  `# Driver code ` `arr ``=` `[``1``, ``20``, ``6``, ``4``, ``5``] ` `n ``=` `len``(arr) ` ` `  `print``(mergeSort(arr, n)) ` ` `  `# This code is contributed by Mohit Kumar `

## C#

 `// C# implementation of the above approach  ` `using` `System; ` ` `  `class` `GFG  ` `{ ` `         `  `    ``// Function that sorts the input array  ` `    ``// and returns the number of inversions  ` `    ``// in the array  ` `    ``static` `int` `mergeSort(``int` `[]arr,  ` `                         ``int` `array_size)  ` `    ``{  ` `        ``int` `[]temp = ``new` `int``[array_size];  ` `        ``return` `_mergeSort(arr, temp, 0,  ` `                          ``array_size - 1);  ` `    ``}  ` `     `  `    ``// Recursive function that sorts the input  ` `    ``// array and returns the number of  ` `    ``// inversions in the array  ` `    ``static` `int` `_mergeSort(``int` `[]arr, ``int` `[]temp, ` `                          ``int` `left, ``int` `right)  ` `    ``{  ` `        ``int` `mid, 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 sum of the  ` `            ``// inversions in the left-part, the right-part  ` `            ``// and the 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);  ` `        ``}  ` `        ``return` `inv_count;  ` `    ``}  ` `     `  `    ``// Function that merges the two sorted arrays  ` `    ``// and returns the inversion count in the arrays  ` `    ``static` `int` `merge(``int` `[]arr, ``int` `[]temp, ``int` `left,  ` `                                ``int` `mid, ``int` `right)  ` `    ``{  ` `        ``int` `i, j, k;  ` `        ``int` `inv_count = 0;  ` `     `  `        ``// i is the index for the left subarray  ` `        ``i = left;  ` `     `  `        ``// j is the index for the right subarray  ` `        ``j = mid;  ` `     `  `        ``// k is the index for the resultant  ` `        ``// merged subarray  ` `        ``k = left;  ` `     `  `        ``// First pass to count number  ` `        ``// of significant inversions  ` `        ``while` `((i <= mid - 1) && (j <= right))  ` `        ``{  ` `            ``if` `(arr[i] > 2 * arr[j])  ` `            ``{  ` `                ``inv_count += (mid - i);  ` `                ``j++;  ` `            ``}  ` `            ``else` `            ``{  ` `                ``i++;  ` `            ``}  ` `        ``}  ` `     `  `        ``// i is the index for the left subarray  ` `        ``i = left;  ` `     `  `        ``// j is the index for the right subarray  ` `        ``j = mid;  ` `     `  `        ``// k is the index for the resultant  ` `        ``// merged subarray  ` `        ``k = left;  ` `     `  `        ``// Second pass to merge the two sorted arrays  ` `        ``while` `((i <= mid - 1) && (j <= right)) ` `        ``{  ` `            ``if` `(arr[i] <= arr[j])  ` `            ``{  ` `                ``temp[k++] = arr[i++];  ` `            ``}  ` `            ``else` `            ``{  ` `                ``temp[k++] = arr[j++];  ` `            ``}  ` `        ``}  ` `     `  `        ``// Copy the remaining elements of the left  ` `        ``// subarray (if there are any) to temp  ` `        ``while` `(i <= mid - 1)  ` `            ``temp[k++] = arr[i++];  ` `     `  `        ``// Copy the remaining elements of the right  ` `        ``// subarray (if there are any) to temp  ` `        ``while` `(j <= right)  ` `            ``temp[k++] = arr[j++];  ` `     `  `        ``// Copy back the merged elements to  ` `        ``// the original array  ` `        ``for` `(i = left; i <= right; i++)  ` `            ``arr[i] = temp[i];  ` `     `  `        ``return` `inv_count;  ` `    ``}  ` `     `  `    ``// Driver code  ` `    ``public` `static` `void` `Main ()  ` `    ``{  ` `        ``int` `[]arr = { 1, 20, 6, 4, 5 };  ` `        ``int` `n = arr.Length;  ` `     `  `        ``Console.WriteLine(mergeSort(arr, n));  ` `    ``}  ` `} ` ` `  `// This code is contributed by anuj_67.. `

Output:

```3
```

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.