Given an array arr[], the goal is to count the number of inversions in all the sub-arrays. An inversion is a pair of indices i and j such that i > j and arr[i] < arr[j]. A sub-array from index x to y ( x<= y) consists of the element’s arr[x], arr[x+1], …, arr[y]. The array arr[] can also contain repeated elements.
Examples:
Input: arr[] = {3, 6, 1, 6, 5, 3, 9}
Output:
0 0 2 2 4 7 7
0 0 1 1 3 6 6
0 0 0 0 1 3 3
0 0 0 0 1 3 3
0 0 0 0 0 1 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
Explanation:
The element in the i’th row and j’th column of the output denotes the number of inversions from index i to j (inclusive). Consider i = 1 and j = 4 (assuming 0-based indexing), the number of inversions in the subarray {6, 1, 6, 5} is 3. The element pairs are (6, 1), (6, 5) and (6, 5) (from the second 6).Input: arr[] = {3, 2, 1}
Output:
0 1 3
0 0 1
0 0 0
Explanation:
From index 0 to 1 there is 1 inversion, from index 2 to 3 there is 1 inversion and from index 0 to 2 there are 3 inversions. The i’th row and j’th column of the output is 0 if i >= j.
Naive Approach: A naive approach is to generate all possible sub-arrays and count the number of inversions in each of the sub-arrays.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to count the number of // inversions in all the sub-arrays void findSubarrayInversions( int arr[], int n)
{ int inversions[n][n];
// Initializing the inversion count
// of each subarray to 0
// inversions[i][j] will denote
// the number of inversions
// from index i to index j inclusive
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
inversions[i][j] = 0;
}
}
// Generating all subarray
for ( int i = 0; i < n; i++) {
for ( int j = i; j < n; j++) {
int ans = 0;
// counting the number of inversions
// for a subarray
for ( int x = i; x <= j; x++) {
for ( int y = x; y <= j; y++) {
if (arr[x] > arr[y])
ans++;
}
}
inversions[i][j] = ans;
}
}
// Printing the number of inversions
// of all subarrays
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
cout << inversions[i][j] << " " ;
}
cout << "\n" ;
}
} // Driver Code int main()
{ // Given Input
int n = 7;
int arr[n] = { 3, 6, 1, 6, 5, 3, 9 };
// Function Call
findSubarrayInversions(arr, n);
} |
// Java program for the above approach class GFG{
// Function to count the number of // inversions in all the sub-arrays static void findSubarrayInversions( int arr[], int n)
{ int [][]inversions = new int [n][n];
// Initializing the inversion count
// of each subarray to 0
// inversions[i][j] will denote
// the number of inversions
// from index i to index j inclusive
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < n; j++)
{
inversions[i][j] = 0 ;
}
}
// Generating all subarray
for ( int i = 0 ; i < n; i++)
{
for ( int j = i; j < n; j++)
{
int ans = 0 ;
// Counting the number of inversions
// for a subarray
for ( int x = i; x <= j; x++)
{
for ( int y = x; y <= j; y++)
{
if (arr[x] > arr[y])
ans++;
}
}
inversions[i][j] = ans;
}
}
// Printing the number of inversions
// of all subarrays
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < n; j++)
{
System.out.print(inversions[i][j] + " " );
}
System.out.println();
}
} // Driver Code public static void main(String args[])
{ // Given Input
int n = 7 ;
int []arr = { 3 , 6 , 1 , 6 , 5 , 3 , 9 };
// Function Call
findSubarrayInversions(arr, n);
} } // This code is contributed by SoumikMondal. |
# Python3 program for the above approach # Function to count the number of # inversions in all the sub-arrays def findSubarrayInversions(arr, n):
inversions = [[ 0 for i in range (n)]
for j in range (n)]
# Initializing the inversion count
# of each subarray to 0
# inversions[i][j] will denote
# the number of inversions
# from index i to index j inclusive
# Generating all subarray
for i in range ( 0 , n):
for j in range ( 0 , n):
ans = 0
# Counting the number of inversions
# for a subarray
for x in range (i, j + 1 ):
for y in range (x, j + 1 ):
if (arr[x] > arr[y]):
ans + = 1
# Print(ans)
inversions[i][j] = ans
# Printing the number of inversions
# of all subarrays
for i in range ( 0 , n):
for j in range ( 0 , n):
print (inversions[i][j], end = " " )
print ()
# Driver Code # Given Input n = 7
arr = [ 3 , 6 , 1 , 6 , 5 , 3 , 9 ]
# Function Call findSubarrayInversions(arr, n) # This code is contributed by amreshkumar3 |
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG{
// Function to count the number of // inversions in all the sub-arrays static void findSubarrayInversions( int []arr, int n)
{ int [,]inversions = new int [n,n];
// Initializing the inversion count
// of each subarray to 0
// inversions[i][j] will denote
// the number of inversions
// from index i to index j inclusive
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
inversions[i,j] = 0;
}
}
// Generating all subarray
for ( int i = 0; i < n; i++)
{
for ( int j = i; j < n; j++)
{
int ans = 0;
// counting the number of inversions
// for a subarray
for ( int x = i; x <= j; x++) {
for ( int y = x; y <= j; y++) {
if (arr[x] > arr[y])
ans++;
}
}
inversions[i,j] = ans;
}
}
// Printing the number of inversions
// of all subarrays
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
Console.Write(inversions[i,j] + " " );
}
Console.WriteLine();
}
} // Driver Code public static void Main()
{ // Given Input
int n = 7;
int []arr = { 3, 6, 1, 6, 5, 3, 9 };
// Function Call
findSubarrayInversions(arr, n);
} } // This code is contributed by ipg2016107. |
<script> // JavaScript program for the above approach // Function to count the number of // inversions in all the sub-arrays function findSubarrayInversions(arr, n) {
let inversions = new Array(n).fill(0).map(() => new Array(n));
// Initializing the inversion count
// of each subarray to 0
// inversions[i][j] will denote
// the number of inversions
// from index i to index j inclusive
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
inversions[i][j] = 0;
}
}
// Generating all subarray
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
let ans = 0;
// counting the number of inversions
// for a subarray
for (let x = i; x <= j; x++) {
for (let y = x; y <= j; y++) {
if (arr[x] > arr[y])
ans++;
}
}
inversions[i][j] = ans;
}
}
// Printing the number of inversions
// of all subarrays
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
document.write(inversions[i][j] + " " );
}
document.write( "<br>" );
}
} // Driver Code // Given Input let n = 7; let arr = [3, 6, 1, 6, 5, 3, 9]; // Function Call findSubarrayInversions(arr, n); </script> |
0 0 2 2 4 7 7 0 0 1 1 3 6 6 0 0 0 0 1 3 3 0 0 0 0 1 3 3 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Time Complexity: O(N4)
Auxiliary Space: O(N2)
Efficient Approach: The above method can be optimized a little using the method given here to find the number of inversions in a sub-array. First see some observations to solve this problem:
First create a 2d array greater[][], where greater[i][j] denotes the number of elements in the range i to j which are greater than arr[i]. Iterate over the array and for each element, find the number of elements to its right which are less than the element. This can be done using a naive approach in O(N^2). Now to find the number of inversions in a range say x to y, the answer will be greater[x][y] + greater[x+1][y] + … + greater[y-1][y] + greater[y][y].
With the greater[][] table this value can be calculated in O(n) for each sub-array resulting in a complexity of O(n^3).(There are O(n^2) sub-array, and it takes O(n) time to compute the number of inversions in each sub-array). To find this value in O(1) each time build a prefix sum table from the greater[][] table where prefix[i][j] denotes the value of greater[0][j] + greater[1][j] + … + greater[i][j]. This table can also be built in O(N^2) time. Now the answer for each sub-array from x to y (inclusive) would become prefix[y][y] – prefix[x-1][y] if x >= 1 and prefix[y][y] if x = 0.
Follow the step below to solve this problem:
- Initialize arrays greater[][] to store where greater[i][j] denotes the number of elements in the range i to j which are greater than arr[i], prefix[][] to store prefix sum for sub-array and inversions[][] to store the number of inversions.
-
Iterate in a range[0, N-1] using a variable i:
-
Iterate in a range[i+1, N-1] using a variable j:
- Update greater[i][j] as greater[i][j-1]
- If arr[i] is greater than arr[j], then Increment greater[i][j] by 1.
-
Iterate in a range[i+1, N-1] using a variable j:
-
Iterate in a range[0, N-1] using a variable i:
- Update prefix[0][j] as greater[0][j]
- Iterate in a range[1, N-1] using a variable j and update prefix[i][j] as prefix[i-1][j] + greater[i][j].
-
Iterate in a range[0, N-1] using a variable i:
-
Iterate in a range[i, N-1] using a variable j:
- If i = 0, then update inversions[i][j] as prefix[j][j]
- Otherwise, update inversions[i][j] as prefix[j][j] + prefix[i-1][j].
-
Iterate in a range[i, N-1] using a variable j:
- After completing the above steps, print inversions[][] array as the answer.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to count the number of // inversions in all the sub-arrays void findSubarrayInversions( int arr[], int n)
{ int greater[n][n];
int prefix[n][n];
int inversions[n][n];
// Initializing the arrays to 0
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
greater[i][j] = 0;
prefix[i][j] = 0;
inversions[i][j] = 0;
}
}
// For each pair of indices i and j
// calculating the number of elements
// from i to j inclusive which are
// greater than arr[i]
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
greater[i][j] = greater[i][j - 1];
if (arr[i] > arr[j])
greater[i][j]++;
}
}
// Building the prefix table.
// Prefix[i][j] denotes the sum of
// greater[0][j], greater[1][j] ... greater[i][j]
for ( int j = 0; j < n; j++) {
prefix[0][j] = greater[0][j];
for ( int i = 1; i < n; i++) {
prefix[i][j] = prefix[i - 1][j] + greater[i][j];
}
}
// Calculating the inversion count for
// each subarray using the prefix table
for ( int i = 0; i < n; i++) {
for ( int j = i; j < n; j++) {
if (i == 0)
inversions[i][j] = prefix[j][j];
else
inversions[i][j] = prefix[j][j]
- prefix[i - 1][j];
}
}
// Printing the values of the number
// of inversions in each subarray
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
cout << inversions[i][j] << " " ;
}
cout << "\n" ;
}
} // Driver Code int main()
{ // Given Input
int n = 7;
int arr[n] = { 3, 6, 1, 6, 5, 3, 9 };
// Function Call
findSubarrayInversions(arr, n);
} |
/*package whatever //do not write package name here */ import java.io.*;
class GFG {
// Function to count the number of
// inversions in all the sub-arrays
static void findSubarrayInversions( int arr[], int n)
{
int greater[][] = new int [n][n];
int prefix[][] = new int [n][n];
int inversions[][] = new int [n][n];
// Initializing the arrays to 0
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
greater[i][j] = 0 ;
prefix[i][j] = 0 ;
inversions[i][j] = 0 ;
}
}
// For each pair of indices i and j
// calculating the number of elements
// from i to j inclusive which are
// greater than arr[i]
for ( int i = 0 ; i < n; i++) {
for ( int j = i + 1 ; j < n; j++) {
greater[i][j] = greater[i][j - 1 ];
if (arr[i] > arr[j])
greater[i][j]++;
}
}
// Building the prefix table.
// Prefix[i][j] denotes the sum of
// greater[0][j], greater[1][j] ... greater[i][j]
for ( int j = 0 ; j < n; j++) {
prefix[ 0 ][j] = greater[ 0 ][j];
for ( int i = 1 ; i < n; i++) {
prefix[i][j] = prefix[i - 1 ][j] + greater[i][j];
}
}
// Calculating the inversion count for
// each subarray using the prefix table
for ( int i = 0 ; i < n; i++) {
for ( int j = i; j < n; j++) {
if (i == 0 )
inversions[i][j] = prefix[j][j];
else
inversions[i][j] = prefix[j][j]
- prefix[i - 1 ][j];
}
}
// Printing the values of the number
// of inversions in each subarray
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
System.out.print(inversions[i][j]+ " " );
}
System.out.println();
}
}
public static void main (String[] args) {
int n = 7 ;
int arr[] = { 3 , 6 , 1 , 6 , 5 , 3 , 9 };
// Function Call
findSubarrayInversions(arr, n);
}
} // This code is contributed by aadityaburujwale. |
# Python3 program for the above approach # Function to count the number of # inversions in all the sub-arrays def findSubarrayInversions(arr, n):
# Initializing the arrays to 0
greater = [[ 0 for i in range (n)]
for j in range (n)]
prefix = [[ 0 for i in range (n)]
for j in range (n)]
inversions = [[ 0 for i in range (n)]
for j in range (n)]
# For each pair of indices i and j
# calculating the number of elements
# from i to j inclusive which are
# greater than arr[i]
for i in range ( 0 , n):
for j in range (i + 1 , n):
greater[i][j] = greater[i][j - 1 ]
if (arr[i] > arr[j]):
greater[i][j] + = 1
# Building the prefix table.
# Prefix[i][j] denotes the sum of
# greater[0][j], greater[1][j] ... greater[i][j]
for j in range ( 0 , n):
prefix[ 0 ][j] = greater[ 0 ][j]
for i in range ( 1 , n):
prefix[i][j] = (prefix[i - 1 ][j] +
greater[i][j])
# Calculating the inversion count for
# each subarray using the prefix table
for i in range ( 0 , n):
for j in range (i, n):
if (i = = 0 ):
inversions[i][j] = prefix[j][j]
else :
inversions[i][j] = (prefix[j][j] -
prefix[i - 1 ][j])
# Printing the values of the number
# of inversions in each subarray
for i in range ( 0 , n):
for j in range ( 0 , n):
print (inversions[i][j], end = " " )
print ()
# Driver Code # Given Input n = 7
arr = [ 3 , 6 , 1 , 6 , 5 , 3 , 9 ]
# Function Call findSubarrayInversions(arr, n) # This code is contributed by amreshkumar3 |
using System;
public class GFG {
// Function to count the number of
// inversions in all the sub-arrays
static void findSubarrayInversions( int [] arr, int n)
{
int [, ] greater = new int [n, n];
int [, ] prefix = new int [n, n];
int [, ] inversions = new int [n, n];
// Initializing the arrays to 0
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
greater[i, j] = 0;
prefix[i, j] = 0;
inversions[i, j] = 0;
}
}
// For each pair of indices i and j
// calculating the number of elements
// from i to j inclusive which are
// greater than arr[i]
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
greater[i, j] = greater[i, j - 1];
if (arr[i] > arr[j])
greater[i, j]++;
}
}
// Building the prefix table.
// Prefix[i][j] denotes the sum of
// greater[0][j], greater[1][j] ... greater[i][j]
for ( int j = 0; j < n; j++) {
prefix[0, j] = greater[0, j];
for ( int i = 1; i < n; i++) {
prefix[i, j]
= prefix[i - 1, j] + greater[i, j];
}
}
// Calculating the inversion count for
// each subarray using the prefix table
for ( int i = 0; i < n; i++) {
for ( int j = i; j < n; j++) {
if (i == 0)
inversions[i, j] = prefix[j, j];
else
inversions[i, j]
= prefix[j, j] - prefix[i - 1, j];
}
}
// Printing the values of the number
// of inversions in each subarray
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
Console.Write(inversions[i, j] + " " );
}
Console.WriteLine();
}
}
public static void Main( string [] args)
{
int n = 7;
int [] arr = { 3, 6, 1, 6, 5, 3, 9 };
// Function Call
findSubarrayInversions(arr, n);
}
} // This code is contributed by krandeep1234. |
<script> // Javascript program for the above approach // Function to count the number of // inversions in all the sub-arrays function findSubarrayInversions(arr, n) {
let greater = new Array(n).fill(0).map(() => new Array(n).fill(0));
let prefix = new Array(n).fill(0).map(() => new Array(n).fill(0));
let inversions = new Array(n).fill(0).map(() => new Array(n).fill(0));
// Initializing the arrays to 0
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
greater[i][j] = 0;
prefix[i][j] = 0;
inversions[i][j] = 0;
}
}
// For each pair of indices i and j
// calculating the number of elements
// from i to j inclusive which are
// greater than arr[i]
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
greater[i][j] = greater[i][j - 1];
if (arr[i] > arr[j]) greater[i][j]++;
}
}
// Building the prefix table.
// Prefix[i][j] denotes the sum of
// greater[0][j], greater[1][j] ... greater[i][j]
for (let j = 0; j < n; j++) {
prefix[0][j] = greater[0][j];
for (let i = 1; i < n; i++) {
prefix[i][j] = prefix[i - 1][j] + greater[i][j];
}
}
// Calculating the inversion count for
// each subarray using the prefix table
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
if (i == 0) inversions[i][j] = prefix[j][j];
else inversions[i][j] = prefix[j][j] - prefix[i - 1][j];
}
}
// Printing the values of the number
// of inversions in each subarray
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
document.write(inversions[i][j] + " " );
}
document.write( "<br>" );
}
} // Driver Code // Given Input let n = 7; let arr = [3, 6, 1, 6, 5, 3, 9]; // Function Call findSubarrayInversions(arr, n); // This code is contributed by saurabh_jaiswal. </script> |
0 0 2 2 4 7 7 0 0 1 1 3 6 6 0 0 0 0 1 3 3 0 0 0 0 1 3 3 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Time Complexity: O(N2)
Space Complexity: O(N2)
Notes-
- Some space can be saved by building the prefix[][] table on top of the greater[][] table but the order will still remain the same.
- It is not possible to perform better than O(N^2) if you want to find the exact count of inversions in all subarrays as the number of subarrays is always O(N^2).