Skip to content
Related Articles
Get the best out of our app
GeeksforGeeks App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Difference between lexicographical ranks of two given permutations

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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);
 
    // Initial 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];
 
    // Initial 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];
 
    // Initial 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

Javascript




<script>
// javascript program for the above approach
 
    // Function the print the difference
    // between the lexicographical ranks
    function findDifference(p,  q , N)
    {
 
        // Store the permutations
        // in lexicographic order
        var A = Array(N).fill(0);
 
        // Initial permutation
        for (var i = 0; i < N; i++)
            A[i] = i + 1;
 
        // Initial variables
        var IsCorrect;
        var a = 1, b = 1;
 
        // Check permutation
        do {
            IsCorrect = true;
            for (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 (i = 0; i < N; i++)
            A[i] = i + 1;
 
        // Check permutation
        do {
            IsCorrect = true;
            for (i = 0; i < N; i++) {
                if (A[i] != q[i]) {
                    IsCorrect = false;
                    break;
                }
            }
            if (IsCorrect)
                break;
 
            b++;
        } while (next_permutation(A));
 
        // Print difference
        document.write(Math.abs(a - b) + "\n");
    }
 
    function next_permutation(p) {
        for (a = p.length - 2; a >= 0; --a)
            if (p[a] < p[a + 1])
 
                for (b = p.length - 1;; --b)
                    if (p[b] > p[a]) {
                        var 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
 
        // Given array P
        var p = [ 1, 3, 2 ];
 
        // Given array Q
        var q = [ 3, 1, 2 ];
 
        // Given size
        var n = p.length;
 
        // Function call
        findDifference(p, q, n);
 
// This code is contributed by umadevi9616
</script>

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)

 

 

 


My Personal Notes arrow_drop_up
Last Updated : 18 Jan, 2022
Like Article
Save Article
Similar Reads
Related Tutorials