Skip to content
Related Articles

Related Articles

Difference between lexicographical ranks of two given permutations
  • Last Updated : 07 Dec, 2020
GeeksforGeeks - Summer Carnival Banner

Given two arrays P[] and Q[] which permutations of first N natural numbers. If P[] and Q[] are the ath and bth lexicographically smallest permutations of [1, N] respectively, the task is to find | a − b |.

Examples :

Input: P[] = {1, 3, 2}, Q[] = {3, 1, 2}
Output: 3
Explanation: 6 permutations of [1, 3] arranged lexicographically are {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}}. Therefore, rank of P[] is 2 and rank of Q[] is 5. Therefore, difference is |2 – 5| = 3.

Input: P[] = {1, 2}, Q[] = {1, 2}
Output: 0
Explanation: 2 permutations of [1, 2] arranged lexicographically are {{1, 2}, {2, 1}}. Therefore, rank of P[] is 1 and rank of Q[] is 1. Therefore, difference is |2-2| = 0.

Approach: Follow the below steps to solve the problem: 



  1. Use the next_permutation() function to find the ranks of both the permutations.
  2. Initialize an array temp[] to store the smallest permutation of first N natural numbers. Also, initialize two variables a and b with 0, to store the lexicographical ranks of the two permutations.
  3. Check if temp[] is equal to P[] or not. If found to be true, break out of the loop. Otherwise, increment a by 1 and check for the next permutation
  4. Similarly, find the lexicographical rank of the permutation Q[] and store it in b.
  5. Finally, print the absolute difference between a and b as the answer.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function the print the difference
// between the lexicographical ranks
void findDifference(vector<int>& p,
                    vector<int>& q, int N)
{
 
    // Store the permutations
// in lexicographic order
    vector<int> A(N);
 
    // Intital permutation
    for (int i = 0; i < N; i++)
        A[i] = i + 1;
 
    // Initial variables
    bool IsCorrect;
    int a = 1, b = 1;
 
    // Check permutation
    do {
        IsCorrect = true;
        for (int i = 0; i < N; i++) {
            if (A[i] != p[i]) {
                IsCorrect = false;
                break;
            }
        }
        if (IsCorrect)
            break;
        a++;
    } while (next_permutation(A.begin(),
                              A.end()));
 
    // Intialize second permutation
    for (int i = 0; i < N; i++)
        A[i] = i + 1;
 
    // Check permutation
    do {
        IsCorrect = true;
        for (int i = 0; i < N; i++) {
            if (A[i] != q[i]) {
                IsCorrect = false;
                break;
            }
        }
        if (IsCorrect)
            break;
        b++;
    } while (next_permutation(A.begin(),
                              A.end()));
 
    // Print difference
    cout << abs(a - b) << endl;
}
 
// Driver Code
int main()
{
 
    // Given array P[]
    vector<int> p = { 1, 3, 2 };
 
    // Given array Q[]
    vector<int> q = { 3, 1, 2 };
 
    // Given size
    int n = p.size();
 
    // Function call
    findDifference(p, q, n);
 
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function the print the difference
// between the lexicographical ranks
static void findDifference(int[] p,
                           int[] q,
                           int N)
{
     
    // Store the permutations
    // in lexicographic order
    int[] A = new int[N];
 
    // Intital permutation
    for(int i = 0; i < N; i++)
        A[i] = i + 1;
 
    // Initial variables
    boolean IsCorrect;
    int a = 1, b = 1;
 
    // Check permutation
    do
    {
        IsCorrect = true;
        for(int i = 0; i < N; i++)
        {
            if (A[i] != p[i])
            {
                IsCorrect = false;
                break;
            }
        }
         
        if (IsCorrect)
            break;
             
        a++;
    } while (next_permutation(A));
 
    // Intialize second permutation
    for(int i = 0; i < N; i++)
        A[i] = i + 1;
 
    // Check permutation
    do
    {
        IsCorrect = true;
        for(int i = 0; i < N; i++)
        {
            if (A[i] != q[i])
            {
                IsCorrect = false;
                break;
            }
        }
        if (IsCorrect)
            break;
             
        b++;
    } while (next_permutation(A));
 
    // Print difference
    System.out.print(Math.abs(a - b) + "\n");
}
 
static boolean next_permutation(int[] p)
{
    for(int a = p.length - 2; a >= 0; --a)
        if (p[a] < p[a + 1])
         
            for(int b = p.length - 1;; --b)
                if (p[b] > p[a])
                {
                    int t = p[a];
                    p[a] = p[b];
                    p[b] = t;
                     
                    for(++a, b = p.length - 1;
                             a < b; ++a, --b)
                    {
                        t = p[a];
                        p[a] = p[b];
                        p[b] = t;
                    }
                    return true;
                }
                 
    return false;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array P[]
    int[] p = { 1, 3, 2 };
 
    // Given array Q[]
    int[] q = { 3, 1, 2 };
 
    // Given size
    int n = p.length;
 
    // Function call
    findDifference(p, q, n);
}
}
 
// This code is contributed by Rajput-Ji

Python3




# Python3 program for the above approach
 
# Function the print the difference
# between the lexicographical ranks
def findDifference(p, q, N):
     
    # Store the permutations
    # in lexicographic order
    A = [0] * N
 
    # Intital permutation
    for i in range(N):
        A[i] = i + 1
 
    # Initial variables
    IsCorrect = False
    a, b = 1, 1
 
    # Check permutation
    while True:
        IsCorrect = True
        for i in range(N):
         
            if (A[i] != p[i]):
                IsCorrect = False
                break
         
        if (IsCorrect):
            break
             
        a += 1
         
        if (not next_permutation(A)):
            break
 
    # Intialize second permutation
    for i in range(N):
        A[i] = i + 1
 
    # Check permutation
    while True:
        IsCorrect = True
        for i in range(N):
         
            if (A[i] != q[i]):
                IsCorrect = False
                break
         
        if (IsCorrect):
            break
             
        b += 1
         
        if (not next_permutation(A)):
            break
 
    # Print difference
    print(abs(a - b))
 
def next_permutation(p):
 
    for a in range(len(p) - 2, -1, -1):
        if (p[a] < p[a + 1]):
             
            b = len(p) - 1
            while True:
                if (p[b] > p[a]):
                    t = p[a]
                    p[a] = p[b]
                    p[b] = t
                     
                    a += 1
                    b = len(p) - 1
                     
                    while a < b:
                        t = p[a]
                        p[a] = p[b]
                        p[b] = t
                        a += 1
                        b -= 1
                         
                    return True
                     
                b -= 1
                 
    return False
 
# Driver Code
 
# Given array P[]
p = [ 1, 3, 2 ]
 
# Given array Q[]
q = [ 3, 1, 2 ]
 
# Given size
n = len(p)
 
# Function call
findDifference(p, q, n)
 
# This code is contributed by divyeshrabadiya07

C#




// C# program for the above approach
using System;
 
class GFG{
 
// Function the print the difference
// between the lexicographical ranks
static void findDifference(int[] p,
                           int[] q,
                           int N)
{
     
    // Store the permutations
    // in lexicographic order
    int[] A = new int[N];
 
    // Intital permutation
    for(int i = 0; i < N; i++)
        A[i] = i + 1;
 
    // Initial variables
    bool IsCorrect;
    int a = 1, b = 1;
 
    // Check permutation
    do
    {
        IsCorrect = true;
        for(int i = 0; i < N; i++)
        {
            if (A[i] != p[i])
            {
                IsCorrect = false;
                break;
            }
        }
         
        if (IsCorrect)
            break;
             
        a++;
    } while (next_permutation(A));
 
    // Intialize second permutation
    for(int i = 0; i < N; i++)
        A[i] = i + 1;
 
    // Check permutation
    do
    {
        IsCorrect = true;
        for(int i = 0; i < N; i++)
        {
            if (A[i] != q[i])
            {
                IsCorrect = false;
                break;
            }
        }
        if (IsCorrect)
            break;
             
        b++;
    } while (next_permutation(A));
 
    // Print difference
    Console.Write(Math.Abs(a - b) + "\n");
}
 
static bool next_permutation(int[] p)
{
    for(int a = p.Length - 2; a >= 0; --a)
        if (p[a] < p[a + 1])
         
            for(int b = p.Length - 1;; --b)
                if (p[b] > p[a])
                {
                    int t = p[a];
                    p[a] = p[b];
                    p[b] = t;
                     
                    for(++a, b = p.Length - 1;
                             a < b; ++a, --b)
                    {
                        t = p[a];
                        p[a] = p[b];
                        p[b] = t;
                    }
                    return true;
                }
                 
    return false;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given array P[]
    int[] p = { 1, 3, 2 };
 
    // Given array Q[]
    int[] q = { 3, 1, 2 };
 
    // Given size
    int n = p.Length;
 
    // Function call
    findDifference(p, q, n);
}
}
 
// This code is contributed by Amit Katiyar
Output: 
3

 

Time Complexity: O(N * max(a, b)) where N is the given size of the permutations and a and b are the lexicographical ranks of the permutations.
Auxiliary Space: O(N)

 

 

 

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :