Skip to content
Related Articles

Related Articles

Improve Article

Difference between lexicographical ranks of two given permutations

  • Last Updated : 29 May, 2021
Geek Week

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()));
 
    // Initialize 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));
 
    // Initialize 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
 
    # Initial 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
 
    # Initialize 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));
 
    // Initialize 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.  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.




My Personal Notes arrow_drop_up
Recommended Articles
Page :