# Significant Inversions in an Array

• Difficulty Level : Medium
• Last Updated : 28 May, 2021

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:
Significant inversion pair are (20, 6), (20, 5) and (20, 4).
Input: arr[] = { 1, 20 }
Output:

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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);` `    ``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..`

## Javascript

 ``
Output:
`3`

My Personal Notes arrow_drop_up