Open In App

Find the count of Reverse pairs

Given an array arr[] of integers, find the count of reverse pairs. A pair of indices (i, j) is said to be a reverse pair if both the following conditions are met:

Examples:



Input: N = 6, arr = [3, 2, 4, 5, 1, 20]
Output: 3
Explanation: The reverse pairs are:

  • (0, 4), arr[0] = 3 and arr[4] = 1, 3 > 2(1)
  • (2, 4), arr[2] = 4 and arr[4] = 1, 4 > 2(1)
  • (3, 4), arr[3] = 5 and arr[4] = 1, 5 > 2(1)

Input: N = 5, arr = [2, 4, 3, 5, 1]
Output: 3
Explanation: The reverse pairs are:



  • (1, 4), arr[1] = 4 and arr[4] = 1, 4 > 2(1)
  • (2, 4), arr[2] = 3 and arr[4] = 1, 3 > 2(1)
  • (3, 4), arr[3] = 5 and arr[4] = 1, 5 > 2(1)

Naïve Approach: To solve the problem follow the below steps:

Below is the implementation of the above approach:




// C++ program to count the reverse pairs
#include <bits/stdc++.h>
using namespace std;
 
// function to count the reverse pairs
int countReversePairs(int arr[], int n)
{
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
 
            // Condition for reverse pairs
            if (arr[i] > 2 * arr[j]) {
                cnt++;
            }
        }
    }
 
    return cnt;
}
 
// Drivers code
int main()
{
 
    int arr[] = { 3, 2, 4, 5, 1, 20 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    cout << "Reverse pairs are: "
         << countReversePairs(arr, n) << endl;
    return 0;
}




public class ReversePairsCount {
 
    // Function to count the reverse pairs
    static int countReversePairs(int[] arr) {
        int cnt = 0;
        int n = arr.length;
 
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
 
                // Condition for reverse pairs
                if (arr[i] > 2 * arr[j]) {
                    cnt++;
                }
            }
        }
 
        return cnt;
    }
 
    public static void main(String[] args) {
        int[] arr = {3, 2, 4, 5, 1, 20};
 
        // Function Call
        System.out.println("Reverse pairs are: " + countReversePairs(arr));
    }
}




# Python program for the above approach:
# function to count the reverse pairs
def countReversePairs(arr, n):
    cnt = 0
    for i in range(0, n):
        for j in range(i + 1, n):
            # Condition for reverse pairs
            if arr[i] > 2 * arr[j]:
                cnt+=1
  
    return cnt
  
# Drivers code
arr = [ 3, 2, 4, 5, 1, 20 ]
n = len(arr)
  
# Function Call
print("Reverse pairs are:", countReversePairs(arr, n))




using System;
 
class Program
{
    // Function to count the reverse pairs
    static int CountReversePairs(int[] arr)
    {
        int cnt = 0;
        int n = arr.Length;
 
        for (int i = 0; i < n; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                // Condition for reverse pairs
                if (arr[i] > 2 * arr[j])
                {
                    cnt++;
                }
            }
        }
 
        return cnt;
    }
 
    static void Main(string[] args)
    {
        int[] arr = { 3, 2, 4, 5, 1, 20 };
 
        // Function Call
        Console.WriteLine("Reverse pairs are: " + CountReversePairs(arr));
    }
}




// Function to count the reverse pairs
function countReversePairs(arr) {
    let cnt = 0;
    const n = arr.length;
 
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
 
            // Condition for reverse pairs
            if (arr[i] > 2 * arr[j]) {
                cnt++;
            }
        }
    }
 
    return cnt;
}
 
const arr = [3, 2, 4, 5, 1, 20];
 
// Function Call
console.log("Reverse pairs are: " + countReversePairs(arr));

Output
Reverse pairs are: 3












Time Complexity: O(N2), two nested loops are used up to N.
Auxiliary Space: O(1), no extra space is used.

Efficient Approach: To solve the problem follow the below idea:

The approach is the same as the merge sort algorithm but the minor difference is that we add an additional function to count the reverse pairs.

The countReversePairs() function will work as follows:

The changes in the mergeSort() function are as follows:

Below is the implementation of the above approach:




// C++ program to count the reverse pairs
#include <iostream>
using namespace std;
 
// Merge function
void merge(int arr[], int low, int mid, int high)
{
 
    int len1 = mid - low + 1;
    int len2 = high - mid;
 
    int* first = new int[len1];
    int* second = new int[len2];
 
    int k = low;
    for (int i = 0; i < len1; i++) {
        first[i] = arr[k++];
    }
 
    k = mid + 1;
    for (int i = 0; i < len2; i++) {
        second[i] = arr[k++];
    }
 
    // Storing the elements in the arr
    // in sorted manner
    int i = 0, j = 0;
    k = low;
    while (i < len1 && j < len2) {
        if (first[i] <= second[j]) {
            arr[k++] = first[i++];
        }
        else {
            arr[k++] = second[j++];
        }
    }
 
    // Storing the left out elements
    // of first half
    while (i < len1) {
        arr[k++] = first[i++];
    }
 
    // Storing the left out elements
    // of right half
    while (j < len2) {
        arr[k++] = second[j++];
    }
}
 
// Function to count the reverse pairs
int countReversePairs(int arr[], int low, int mid, int high)
{
    int cnt = 0;
    int j = mid + 1;
    for (int i = low; i <= mid; i++) {
        while (i <= high && arr[i] > 2 * arr[j]) {
            j++;
        }
        cnt += (j - (mid + 1));
    }
 
    return cnt;
}
 
int mergeSort(int arr[], int low, int high)
{
    int cnt = 0;
    int mid = low + (high - low) / 2;
    if (low >= high) {
        return cnt;
    }
 
    // Count the left half pairs
    cnt += mergeSort(arr, low, mid);
 
    // Count the right half pairs
    cnt += mergeSort(arr, mid + 1, high);
 
    // Function call to count the reverse pairs
    cnt += countReversePairs(arr, low, mid, high);
 
    // Merging the first and second half
    merge(arr, low, mid, high);
 
    return cnt;
}
 
// Drivers code
int main()
{
 
    int arr[] = { 3, 2, 4, 5, 1, 20 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    cout << "Reverse pairs are: "
         << mergeSort(arr, 0, n - 1) << endl;
    return 0;
}




public class ReversePairsCount {
 
    // Merge function to merge two sorted subarrays
    static void merge(int[] arr, int low, int mid, int high) {
        // Calculate the lengths of the two subarrays
        int len1 = mid - low + 1;
        int len2 = high - mid;
 
        // Create temporary arrays to hold the subarrays
        int[] first = new int[len1];
        int[] second = new int[len2];
 
        // Copy data from the main array to the temporary arrays
        int k = low;
        for (int i = 0; i < len1; i++) {
            first[i] = arr[k++];
        }
 
        k = mid + 1;
        for (int i = 0; i < len2; i++) {
            second[i] = arr[k++];
        }
 
        // Merge the two subarrays back into the main array
        int i = 0, j = 0;
        k = low;
        while (i < len1 && j < len2) {
            // Compare and merge elements in sorted order
            if (first[i] <= second[j]) {
                arr[k++] = first[i++];
            } else {
                arr[k++] = second[j++];
            }
        }
 
        // Copy any remaining elements from the temporary arrays
        while (i < len1) {
            arr[k++] = first[i++];
        }
 
        while (j < len2) {
            arr[k++] = second[j++];
        }
    }
 
    // Function to count the reverse pairs using merge sort
    static int countReversePairs(int[] arr, int low, int mid, int high) {
        int cnt = 0;
        int j = mid + 1;
        for (int i = low; i <= mid; i++) {
            while (i <= high && arr[i] > 2 * arr[j]) {
                j++;
            }
            cnt += (j - (mid + 1));
        }
        return cnt;
    }
 
    // Merge Sort function to sort the array and count reverse pairs
    static int mergeSort(int[] arr, int low, int high) {
        int cnt = 0;
        if (low >= high) {
            return cnt;
        }
        int mid = low + (high - low) / 2;
 
        // Recursively count reverse pairs in left and right halves
        cnt += mergeSort(arr, low, mid);
        cnt += mergeSort(arr, mid + 1, high);
 
        // Merge the sorted halves and count reverse pairs
        cnt += countReversePairs(arr, low, mid, high);
 
        // Merge the two halves
        merge(arr, low, mid, high);
 
        return cnt;
    }
 
    public static void main(String[] args) {
        int[] arr = {3, 2, 4, 5, 1, 20};
        int n = arr.length;
 
        // Function Call to count reverse pairs
        System.out.println("Reverse pairs are: " + mergeSort(arr, 0, n - 1));
    }
}




# Python program for the above approach:
 
# Merge function
def merge(arr, low, mid, high):
 
    len1 = mid - low + 1;
    len2 = high - mid;
 
    first = [0]*len1;
    second = [0]*len2;
 
    k = low
    for i in range(0, len1):
        first[i] = arr[k]
        k+=1
 
    k = mid + 1;
    for i in range(0, len2):
        second[i] = arr[k]
        k+=1
 
    # Storing the elements in the arr
    # in sorted manner
    i = 0
    j = 0
    k = low
    while i < len1 and j < len2:
        if first[i] <= second[j]:
            arr[k] = first[i]
            k+=1
            i+=1
        else:
            arr[k] = second[j];
            k+=1
            j+=1
 
    # Storing the left out elements
    # of first half
    while i < len1:
        arr[k] = first[i];
        k+=1
        i+=1
 
    # Storing the left out elements
    # of right half
    while j < len2:
        arr[k] = second[j]
        j+=1
        k+=1
 
# Function to count the reverse pairs
def countReversePairs(arr, low, mid, high):
    cnt = 0
    j = mid + 1
    for i in range(low, mid+1):
        while i <= high and arr[i] > 2*arr[j]:
            j+=1
        cnt += (j - (mid + 1))
 
    return cnt
 
def mergeSort(arr, low, high):
    cnt = 0;
    mid = low + (high - low) // 2;
    if low >= high:
        return cnt
 
    # Count the left half pairs
    cnt += mergeSort(arr, low, mid)
 
    # Count the right half pairs
    cnt += mergeSort(arr, mid + 1, high)
 
    # Function call to count the reverse pairs
    cnt += countReversePairs(arr, low, mid, high)
 
    # Merging the first and second half
    merge(arr, low, mid, high)
 
    return cnt
 
# Drivers code
arr = [3, 2, 4, 5, 1, 20]
n = len(arr)
 
# Function Call
print("Reverse pairs are:", mergeSort(arr, 0, n - 1))




using System;
 
class Program {
    // Merge function to merge two sorted subarrays
    static void Merge(int[] arr, int low, int mid, int high) {
        // Calculate the lengths of the two subarrays
        int len1 = mid - low + 1;
        int len2 = high - mid;
 
        // Create temporary arrays to hold the subarrays
        int[] first = new int[len1];
        int[] second = new int[len2];
 
        // Copy data from the main array to the temporary arrays
        int k = low;
        for (int i = 0; i < len1; i++) {
            first[i] = arr[k++];
        }
 
        k = mid + 1;
        for (int i = 0; i < len2; i++) {
            second[i] = arr[k++];
        }
 
        // Merge the two subarrays back into the main array
        int i = 0, j = 0;
        k = low;
        while (i < len1 && j < len2) {
            // Compare and merge elements in sorted order
            if (first[i] <= second[j]) {
                arr[k++] = first[i++];
            } else {
                arr[k++] = second[j++];
            }
        }
 
        // Copy any remaining elements from the temporary arrays
        while (i < len1) {
            arr[k++] = first[i++];
        }
 
        while (j < len2) {
            arr[k++] = second[j++];
        }
    }
 
    // Function to count the reverse pairs using merge sort
    static int CountReversePairs(int[] arr, int low, int mid, int high) {
        int cnt = 0;
        int j = mid + 1;
        for (int i = low; i <= mid; i++) {
            while (i <= high && arr[i] > 2 * arr[j]) {
                j++;
            }
            cnt += (j - (mid + 1));
        }
        return cnt;
    }
 
    // Merge Sort function to sort the array and count reverse pairs
    static int MergeSort(int[] arr, int low, int high) {
        int cnt = 0;
        if (low >= high) {
            return cnt;
        }
        int mid = low + (high - low) / 2;
 
        // Recursively count reverse pairs in left and right halves
        cnt += MergeSort(arr, low, mid);
        cnt += MergeSort(arr, mid + 1, high);
 
        // Merge the sorted halves and count reverse pairs
        cnt += CountReversePairs(arr, low, mid, high);
 
        // Merge the two halves
        Merge(arr, low, mid, high);
 
        return cnt;
    }
 
    static void Main(string[] args) {
        int[] arr = { 3, 2, 4, 5, 1, 20 };
        int n = arr.Length;
 
        // Function Call to count reverse pairs
        Console.WriteLine("Reverse pairs are: " + MergeSort(arr, 0, n - 1));
    }
}




// Merge function to merge two sorted subarrays
function merge(arr, low, mid, high) {
    // Calculate the lengths of the two subarrays
    const len1 = mid - low + 1;
    const len2 = high - mid;
 
    // Create arrays to hold the subarrays
    const first = new Array(len1);
    const second = new Array(len2);
 
    // Copy data from the main array to the temporary arrays
    let k = low;
    for (let i = 0; i < len1; i++) {
        first[i] = arr[k++];
    }
 
    k = mid + 1;
    for (let i = 0; i < len2; i++) {
        second[i] = arr[k++];
    }
 
    // Merge the two subarrays back into the main array
    let i = 0, j = 0;
    k = low;
    while (i < len1 && j < len2) {
        // Compare and merge elements in sorted order
        if (first[i] <= second[j]) {
            arr[k++] = first[i++];
        } else {
            arr[k++] = second[j++];
        }
    }
 
    // Copy any remaining elements from the temporary arrays
    while (i < len1) {
        arr[k++] = first[i++];
    }
 
    while (j < len2) {
        arr[k++] = second[j++];
    }
}
 
// Function to count the reverse pairs using merge sort
function countReversePairs(arr, low, mid, high) {
    let cnt = 0;
    let j = mid + 1;
    for (let i = low; i <= mid; i++) {
        while (i <= high && arr[i] > 2 * arr[j]) {
            j++;
        }
        cnt += (j - (mid + 1));
    }
    return cnt;
}
 
// Merge Sort function to sort the array and count reverse pairs
function mergeSort(arr, low, high) {
    let cnt = 0;
    if (low >= high) {
        return cnt;
    }
    const mid = low + Math.floor((high - low) / 2);
 
    // Recursively count reverse pairs in left and right halves
    cnt += mergeSort(arr, low, mid);
    cnt += mergeSort(arr, mid + 1, high);
 
    // Merge the sorted halves and count reverse pairs
    cnt += countReversePairs(arr, low, mid, high);
 
    // Merge the two halves
    merge(arr, low, mid, high);
 
    return cnt;
}
 
const arr = [3, 2, 4, 5, 1, 20];
 
// Function Call to count reverse pairs
console.log("Reverse pairs are: " + mergeSort(arr, 0, arr.length - 1));

Output
Reverse pairs are: 3












Complexity Analysis:


Article Tags :