Open In App

Find the count of Reverse pairs

Last Updated : 16 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • 0 <= i < j < N 
  • arr[i] > 2 * arr[j]

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:

  • Run the outer loop(say i) from 0 to N-1.
  • As the index j should be greater than I, so run the inner loop(say j) from i+1 to N-1.
  • If the condition arr[i] > 2*arr[j] is satisfied, then increment the cnt.
  • Return the cnt i.e. the count of reverse pairs.

Below is the implementation of the above approach:

C++




// 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;
}


Java




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));
    }
}


Python3




# 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))


C#




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));
    }
}


Javascript




// 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:

  • Initialize the cnt variable with zero.
  • Run a loop(say i) from low to mid i.e. for the left half.
  • Run another loop(say j) for the right half which starts from the mid+1 and ends at high.
  • If arr[i] > 2* arr[j], then increment the cnt variable.
  • Else, increment the cnt by j-(mid+1).
  • Either if i reaches mid or j reaches end(>=high) return the cnt.

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

  • Initialize the cnt variable with zero.
  • Add the count of reverse pairs in the cnt variable return by the previous mergeSort() function.
  • Before calling the merge() function count the number of reverse pairs.
  • If the low becomes greater than equal to the high, return the cnt (the left half starts from the low and ends at mid and the right half starts from mid+1 and ends at high).

Below is the implementation of the above approach:

C++




// 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;
}


Java




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));
    }
}


Python3




# 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))


C#




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));
    }
}


Javascript




// 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:

  • Time Complexity: O(N*log(N)), the time complexity of the mergeSort() function is O(N*logN) and the countReversePairs() function and merge() function is called inside the mergeSort() function whose time complexity is O(N) for each function. So, the overall time complexity of the function is O(logN)*O(N).
  • Auxiliary Space: O(N), as the extra array is used to store the elements.


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads