Open In App

Difference between lexicographical ranks of two given permutations

Last Updated : 18 Jan, 2022
Comments
Improve
Suggest changes
Like Article
Like
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)


 


 


 


Next Article

Similar Reads