Open In App

Difference between lexicographical ranks of two given permutations

Improve
Improve
Like Article
Like
Save
Share
Report

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)

 

 

 



Last Updated : 18 Jan, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads