Open In App

Lexicographically largest permutation transformation

Last Updated : 14 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an arr[] of size n, the task is to find the lexicographically largest permutation from the given permutation by performing the following operations exactly once where you will choose two integers l and r and reverse the subarray [l, r] and swap [1, l-1] with [r+1, n].

Examples:

Input: arr[] = { 2, 3, 1, 5, 4}
Output: {5, 4, 1, 3, 2 }
Explanation: we will choose l = 2 and r =3, then after performing operation, the permutation will be {5, 4, 3, 1, 2 }

Input: arr[] = { 6, 1,  2, 3, 5, 4 }
Output: {5, 4, 3, 6, 1, 2 }
Explanation: we will choose l = 4 and r  = 4, then after performing the operation, the permutation will be {5, 4, 3, 6, 1, 2}

Approach: To solve the problem follow the below idea:

There will be two cases: 

  • If arr[0] = n  . if arr[1] == n-1, then choose l = 0 and  r = 0. Else let arr[j] = n-1, then choose l = j-1 and  r = j-19(0-based indexing ) .
  • If arr[0] != n . let arr[j] = n, then iterate while loop from j-1 to 0 till arr[i] > arr[0]  and decrease i by 1, then our l will be i and r will be j.

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to print new lexographically
// largest permutation from a given
// permuatation by performing exactly
// one operation
void lexogra_permutation(int* arr, int n)
{
    int j, k;
 
    // New lexographically largest
    // permutation
    vector<int> permu;
 
    // If first element is equal to n
    if (arr[0] == n) {
 
        // If second element equal to n
        if (arr[1] == n - 1) {
 
            // Inserting subarray[1, n-1]
            // in permu
            for (int i = 1; i < n; i++) {
                permu.push_back(arr[i]);
            }
 
            // Inserting subarray[0, 0] in
            // permu
            permu.push_back(arr[0]);
        }
        else {
 
            // Find value of j such that
            // a[j] = n
            for (int i = 1; i < n; i++) {
 
                // if j found, then break
                if (arr[i] == n - 1) {
                    j = i;
                    break;
                }
            }
 
            // Inserting subarray[j, n-1]
            // in permu
            for (int i = j; i < n; i++) {
                permu.push_back(arr[i]);
            }
 
            // Inserting subarray[j-1, j-1]
            // in permu
            permu.push_back(arr[j - 1]);
 
            // Inserting subarray[0, j-1]
            // in permu
            for (int i = 0; i < j - 1; i++) {
                permu.push_back(arr[i]);
            }
        }
    }
 
    // If first element isn't
    // equal to n
    else {
 
        for (int i = 0; i < n; i++) {
 
            // If j found, then break
            if (arr[i] == n) {
                j = i;
                break;
            }
        }
        k = j - 2;
 
        // Till k is >= 0 & a[k] greater
        // than arr[0]
        while (k >= 0 && arr[k] > arr[0]) {
            if (arr[k - 1] > arr[0] && k - 1 >= 0) {
                k--;
            }
            else {
                break;
            }
        }
 
        // Inserting subarray[j, n-1] in
        // permu
        for (int i = j; i < n; i++) {
            permu.push_back(arr[i]);
        }
 
        // Inserting reverse of
        // subarray[k, j-1] in permu
        for (int i = j - 1; i >= k; i--) {
            permu.push_back(arr[i]);
        }
 
        // Inserting subarray[0, k-1]
        // in permu
        for (int i = 0; i < k; i++) {
            permu.push_back(arr[i]);
        }
    }
 
    // Lexographically largest
    // new permutation
    for (int i = 0; i < permu.size(); i++) {
        cout << permu[i] << " ";
    }
}
 
// Driver code
int main()
{
    int arr[] = { 2, 3, 1, 5, 4 };
    int n = sizeof(arr) / sizeof(int);
 
    // Function call
    lexogra_permutation(arr, n);
 
    return 0;
}


Java




// JAVA code for the above approach
 
import java.util.*;
 
class GFG {
    // Function to print new lexicographically
    // largest permutation from a given
    // permutation by performing exactly
    // one operation
    public static void lexograPermutation(int[] arr, int n)
    {
        int j = 0, k;
 
        // New lexicographically largest
        // permutation
        ArrayList<Integer> permu = new ArrayList<>();
 
        // If first element is equal to n
        if (arr[0] == n) {
            // If second element equal to n - 1
            if (arr[1] == n - 1) {
                // Inserting subarray [1, n-1] in permu
                for (int i = 1; i < n; i++) {
                    permu.add(arr[i]);
                }
                // Inserting subarray [0, 0] in permu
                permu.add(arr[0]);
            }
            else {
                // Find value of j such that a[j] = n
                for (int i = 1; i < n; i++) {
                    // If j found, then break
                    if (arr[i] == n - 1) {
                        j = i;
                        break;
                    }
                }
                // Inserting subarray [j, n-1] in permu
                for (int i = j; i < n; i++) {
                    permu.add(arr[i]);
                }
                // Inserting subarray [j-1, j-1] in permu
                permu.add(arr[j - 1]);
                // Inserting subarray [0, j-1] in permu
                for (int i = 0; i < j - 1; i++) {
                    permu.add(arr[i]);
                }
            }
        }
        // If first element isn't equal to n
        else {
            for (int i = 0; i < n; i++) {
                // If j found, then break
                if (arr[i] == n) {
                    j = i;
                    break;
                }
            }
            k = j - 2;
            // Till k is >= 0 & arr[k] greater than arr[0]
            while (k >= 0 && arr[k] > arr[0]) {
                if (arr[k - 1] > arr[0] && k - 1 >= 0) {
                    k--;
                }
                else {
                    break;
                }
            }
            // Inserting subarray [j, n-1] in permu
            for (int i = j; i < n; i++) {
                permu.add(arr[i]);
            }
            // Inserting reverse of subarray [k, j-1] in
            // permu
            for (int i = j - 1; i >= k; i--) {
                permu.add(arr[i]);
            }
            // Inserting subarray [0, k-1] in permu
            for (int i = 0; i < k; i++) {
                permu.add(arr[i]);
            }
        }
        // Lexicographically largest new permutation
        for (int i = 0; i < permu.size(); i++) {
            System.out.print(permu.get(i) + " ");
        }
    }
 
    // Driver code
 
    // Driver code
    public static void main(String[] args)
    {
        int[] arr = { 2, 3, 1, 5, 4 };
        int n = arr.length;
 
        // Function call
        lexograPermutation(arr, n);
    }
}
 
// This code is contributed by shivamgupta310570


Python3




# Python3 code for the above approach
def lexogra_permutation(arr, n):
    # New lexographically largest permutation
    permu = []
 
    # If first element is equal to n
    if arr[0] == n:
        # If second element equal to n-1
        if arr[1] == n - 1:
            # Inserting subarray [1, n-1] in permu
            for i in range(1, n):
                permu.append(arr[i])
            # Inserting subarray [0, 0] in permu
            permu.append(arr[0])
        else:
            # Find value of j such that a[j] = n
            for i in range(1, n):
                # if j found, then break
                if arr[i] == n - 1:
                    j = i
                    break
            # Inserting subarray [j, n-1] in permu
            for i in range(j, n):
                permu.append(arr[i])
            # Inserting subarray [j-1, j-1] in permu
            permu.append(arr[j - 1])
            # Inserting subarray [0, j-1] in permu
            for i in range(0, j - 1):
                permu.append(arr[i])
    else:
        # If first element isn't equal to n
        for i in range(n):
            # If j found, then break
            if arr[i] == n:
                j = i
                break
        k = j - 2
        # Till k is >= 0 & a[k] greater than arr[0]
        while k >= 0 and arr[k] > arr[0]:
            if arr[k - 1] > arr[0] and k - 1 >= 0:
                k -= 1
            else:
                break
        # Inserting subarray [j, n-1] in permu
        for i in range(j, n):
            permu.append(arr[i])
        # Inserting reverse of subarray [k, j-1] in permu
        for i in range(j - 1, k - 1, -1):
            permu.append(arr[i])
        # Inserting subarray [0, k-1] in permu
        for i in range(k):
            permu.append(arr[i])
 
    # Lexographically largest new permutation
    for i in range(len(permu)):
        print(permu[i], end=" ")
 
 
# Driver code
arr = [2, 3, 1, 5, 4]
n = len(arr)
 
# Function call
lexogra_permutation(arr, n)
 
# This code is contributed by shivamgupta0987654321


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
    // Function to print new lexographically
    // largest permutation from a given
    // permutation by performing exactly
    // one operation
    static void LexograPermutation(int[] arr, int n)
    {
        int j = 0, k = 0;
 
        // New lexographically largest permutation
        List<int> permu = new List<int>();
 
        // If the first element is equal to n
        if (arr[0] == n) {
            // If the second element is equal to n - 1
            if (arr[1] == n - 1) {
                // Inserting subarray [1, n - 1] in permu
                for (int i = 1; i < n; i++) {
                    permu.Add(arr[i]);
                }
 
                // Inserting subarray [0, 0] in permu
                permu.Add(arr[0]);
            }
            else {
                // Find the value of j such that a[j] = n
                for (int i = 1; i < n; i++) {
                    // if j is found, then break
                    if (arr[i] == n - 1) {
                        j = i;
                        break;
                    }
                }
 
                // Inserting subarray [j, n - 1] in permu
                for (int i = j; i < n; i++) {
                    permu.Add(arr[i]);
                }
 
                // Inserting subarray [j - 1, j - 1] in
                // permu
                permu.Add(arr[j - 1]);
 
                // Inserting subarray [0, j - 1] in permu
                for (int i = 0; i < j - 1; i++) {
                    permu.Add(arr[i]);
                }
            }
        }
        else {
            for (int i = 0; i < n; i++) {
                // If j is found, then break
                if (arr[i] == n) {
                    j = i;
                    break;
                }
            }
            k = j - 2;
 
            // Till k is >= 0 & a[k] is greater than arr[0]
            while (k >= 0 && arr[k] > arr[0]) {
                if (arr[k - 1] > arr[0] && k - 1 >= 0) {
                    k--;
                }
                else {
                    break;
                }
            }
 
            // Inserting subarray [j, n - 1] in permu
            for (int i = j; i < n; i++) {
                permu.Add(arr[i]);
            }
 
            // Inserting reverse of subarray [k, j - 1] in
            // permu
            for (int i = j - 1; i >= k; i--) {
                permu.Add(arr[i]);
            }
 
            // Inserting subarray [0, k - 1] in permu
            for (int i = 0; i < k; i++) {
                permu.Add(arr[i]);
            }
        }
 
        // Lexographically largest new permutation
        foreach(var element in permu)
        {
            Console.Write(element + " ");
        }
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 2, 3, 1, 5, 4 };
        int n = arr.Length;
 
        // Function call
        LexograPermutation(arr, n);
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// JavaScript code for the above approach
 
// Function to print new lexicographically
// largest permutation from a given
// permutation by performing exactly
// one operation
function lexogra_permutation(arr, n) {
    let j, k;
 
    // New lexicographically largest
    // permutation
    let permu = [];
 
    // If first element is equal to n
    if (arr[0] === n) {
        // If second element equal to n - 1
        if (arr[1] === n - 1) {
            // Inserting subarray[1, n-1]
            // in permu
            for (let i = 1; i < n; i++) {
                permu.push(arr[i]);
            }
 
            // Inserting subarray[0, 0] in
            // permu
            permu.push(arr[0]);
        } else {
            // Find value of j such that
            // a[j] = n
            for (let i = 1; i < n; i++) {
                // if j found, then break
                if (arr[i] === n - 1) {
                    j = i;
                    break;
                }
            }
 
            // Inserting subarray[j, n-1]
            // in permu
            for (let i = j; i < n; i++) {
                permu.push(arr[i]);
            }
 
            // Inserting subarray[j-1, j-1]
            // in permu
            permu.push(arr[j - 1]);
 
            // Inserting subarray[0, j-1]
            // in permu
            for (let i = 0; i < j - 1; i++) {
                permu.push(arr[i]);
            }
        }
    }
    // If first element isn't equal to n
    else {
        for (let i = 0; i < n; i++) {
            // If j found, then break
            if (arr[i] === n) {
                j = i;
                break;
            }
        }
        k = j - 2;
 
        // Till k is >= 0 & a[k] greater
        // than arr[0]
        while (k >= 0 && arr[k] > arr[0]) {
            if (arr[k - 1] > arr[0] && k - 1 >= 0) {
                k--;
            } else {
                break;
            }
        }
 
        // Inserting subarray[j, n-1] in
        // permu
        for (let i = j; i < n; i++) {
            permu.push(arr[i]);
        }
 
        // Inserting reverse of
        // subarray[k, j-1] in permu
        for (let i = j - 1; i >= k; i--) {
            permu.push(arr[i]);
        }
 
        // Inserting subarray[0, k-1]
        // in permu
        for (let i = 0; i < k; i++) {
            permu.push(arr[i]);
        }
    }
 
    // Lexicographically largest
    // new permutation
    for (let i = 0; i < permu.length; i++) {
        document.write(permu[i] + " ");
    }
}
 
// Driver code
const arr = [2, 3, 1, 5, 4];
const n = arr.length;
 
// Function call
lexogra_permutation(arr, n);
 
// This code is contributed by Susobhan Akhuli


Output

5 4 1 3 2 

Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads