Given an array A[] of size N where each element A[i] =max(P[0], P[1], . . ., P[i]), where P[] is a permutation consisting of elements from 1 to N, the task is to find the lexicographically smallest and lexicographically largest permutation that satisfies A[].
Examples:
Input: A[] = {3, 4, 5, 5, 5, 7, 7}
Output: Lexicographically smallest permutation is: {3 4 5 1 2 7 6}.
Lexicographically largest permutation is: { 3 4 5 2 1 7 6}Input: A[] = {2, 4, 4, 4, 6, 6}
Output: Lexicographically smallest permutation is: 2 4 1 3 6 5
Lexicographically largest permutation is: 2 4 3 1 6 5
Approach: This problem can be solved using this idea:
Use a set to store the first N natural number and for each element of A, find the lexicographical element satisfying A using property of set that it stores values in sorted order.
To make a permutation array, push all the natural numbers from 1 to N into a set because every element is required only once.
- For minimum permutation, initialize the curr_max variable to 0 and traverse the array:
- If the curr_max is less than A[i] choose the A[i] and put it into the permutation and remove A[i] from set updating curr_max = A[i].
- Otherwise, from the set, put the first number from the set into the position to make permutation lexicographically minimum and remove the first element of the set.
- Second, For maximal permutation, again initialize the curr_max variable to 0 and traverse the array:
- If the curr_max is less than A[i] choose the A[i] and put it into the permutation and remove A[i] from set updating curr_max = A[i].
- Otherwise, check the lower bound of A[i] and decrement the iterator to get the largest number smaller than A[i] in the set, and remove it from the set.
- Let's say the minimum permutation obtained is called mini and the maximum permutation obtained maxi and return that
Below is the implementation of the above approach.
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to return the max array of
// minimum and maximum permutation
// satisfying A
void findMinMaxPermutation(vector<int>& A)
{
int n = A.size();
set<int> s;
vector<int> mini;
vector<int> maxi;
// Pushing all the elements into set till n
for (int i = 1; i < n + 1; i++)
s.insert(i);
int curr_max = 0;
for (int i = 0; i < n; i++) {
int number;
// If curr_max is less
if (curr_max < A[i]) {
number = A[i];
}
// Choosing the smallest element less than A[i]
else
number = *s.begin();
// Erasing from set
s.erase(number);
// Pushing the elements to vector
mini.push_back(number);
// Keep updating the max
curr_max = max(curr_max, mini.back());
}
curr_max = 0;
// Pushing all the elements into set till n
for (int i = 1; i < n + 1; i++)
s.insert(i);
for (int i = 0; i < n; i++) {
int number;
// If curr_max is less
if (curr_max < A[i])
number = A[i];
// Choosing the bigger element but less than A[i]
else
number = *(--(s.lower_bound(A[i])));
// Erasing from set
s.erase(number);
// Pushing the elements to vector
maxi.push_back(number);
// Keep updating the max
curr_max = max(curr_max, maxi.back());
}
cout << "Lexicographically smallest permutation is : ";
for (auto i : mini)
cout << i << " ";
cout << endl;
cout << "Lexicographically largest permutation is : ";
for (auto i : maxi)
cout << i << " ";
cout << endl;
}
// Driver Code
int main()
{
vector<int> A{ 2, 4, 4, 4, 6, 6 };
// Function call
findMinMaxPermutation(A);
return 0;
}
/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG
{
// Function to return the max array of
// minimum and maximum permutation
// satisfying A
public static void
findMinMaxPermutation(List<Integer> A)
{
int n = A.size();
// set<Integer> s;
HashSet<Integer> s = new HashSet<Integer>();
List<Integer> mini = new ArrayList<Integer>();
List<Integer> maxi = new ArrayList<Integer>();
// Pushing all the elements into set till n
for (int i = 1; i < n + 1; i++)
s.add(i);
int curr_max = 0;
for (int i = 0; i < n; i++) {
int number = Integer.MAX_VALUE;
// If curr_max is less
if (curr_max < A.get(i)) {
number = A.get(i);
}
// Choosing the smallest element less than A[i]
else
for (int var : s) {
// For elements in Set
if (var < number)
// Update the minimum element
number = var;
}
// Erasing from set
s.remove(number);
// Pushing the elements to vector
mini.add(number);
// Keep updating the max
curr_max = Math.max(curr_max,
mini.get(mini.size() - 1));
}
curr_max = 0;
// Pushing all the elements into set till n
for (int i = 1; i < n + 1; i++)
s.add(i);
for (int i = 0; i < n; i++) {
int number = 0;
// If curr_max is less
if (curr_max < A.get(i))
number = A.get(i);
// Choosing the bigger element but less than
// A[i]
else {
for (int num : s) {
if (num <= A.get(i))
number = Math.max(number, num);
}
}
// Erasing from set
s.remove(number);
// Pushing the elements to vector
maxi.add(number);
// Keep updating the max
curr_max = Math.max(curr_max,
maxi.get(maxi.size() - 1));
}
System.out.print(
"Lexicographically smallest permutation is : ");
for (int i : mini)
System.out.print(i + " ");
System.out.println("");
System.out.print(
"Lexicographically largest permutation is : ");
for (int i : maxi)
System.out.print(i + " ");
System.out.println("");
}
public static void main(String[] args)
{
List<Integer> A = new ArrayList<Integer>(
Arrays.asList(2, 4, 4, 4, 6, 6));
// Function call
findMinMaxPermutation(A);
}
}
// This code is contributed by akashish__
# Python code for the above approach
# import the module
import math
# Function to return the max array of
# minimum and maximum permutation satisfying A
def findMinMaxPermutation(A):
n = len(A)
# set s
s = set()
mini = []
maxi = []
# Pushing all the elements into set till n
for i in range(1, n+1):
s.add(i)
curr_max = 0
for i in range(n):
number = math.inf
# If curr_max is less
if(curr_max < A[i]):
number = A[i]
# Choosing the smallest element less than A[i]
else:
for var in s:
# For elements in Set
if(var < number):
# Update the minimum element
number = var
# Erasing from set
s.remove(number)
# Pushing the elements to vector
mini.append(number)
# Keep updating the max
curr_max = max(curr_max, mini[len(mini)-1])
curr_max = 0
# Pushing all the elements into set till n
for i in range(1, n+1):
s.add(i)
for i in range(n):
number = 0
# If curr_max is less
if(curr_max < A[i]):
number = A[i]
# Choosing the bigger element but less than A[i]
else:
for num in s:
if(num <= A[i]):
number = max(number, num)
# Erasing from set
s.remove(number)
# Pushing the elements to vector
maxi.append(number)
# Keep updating the max
curr_max = max(curr_max, maxi[len(maxi)-1])
print("Lexicographically smallest permutation is :", end=" ")
for i in mini:
print(i, end=" ")
print()
print("Lexicographically largest permutation is :", end=" ")
for i in maxi:
print(i, end=" ")
print()
A = [2, 4, 4, 4, 6, 6]
# Function call
findMinMaxPermutation(A)
# This code is contributed by lokeshmvs21.
// C# code for the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to return the max array of minimum and
// maximum permutation satisfying A
static void findMinMaxPermutation(List<int> A)
{
int n = A.Count;
// set<Integer> s;
HashSet<int> s = new HashSet<int>();
List<int> mini = new List<int>();
List<int> maxi = new List<int>();
// Pushing all the elements into set till n
for (int i = 1; i < n + 1; i++) {
s.Add(i);
}
int curr_max = 0;
for (int i = 0; i < n; i++) {
int number = Int32.MaxValue;
// If curr_max is less
if (curr_max < A[i]) {
number = A[i];
}
// Choosing the smallest element less than A[i]
else {
foreach(var Var in s)
{
// For elements in Set
if (Var < number) {
// Update the minimum element
number = Var;
}
}
}
// Erasing from set
s.Remove(number);
// Pushing the elements to vector
mini.Add(number);
// Keep updating the max
curr_max
= Math.Max(curr_max, mini[mini.Count - 1]);
}
curr_max = 0;
// Pushing all the elements into set till n
for (int i = 1; i < n + 1; i++) {
s.Add(i);
}
for (int i = 0; i < n; i++) {
int number = 0;
// If curr_max is less
if (curr_max < A[i]) {
number = A[i];
}
// Choosing the bigger element but less than
// A[i]
else {
foreach(var num in s)
{
if (num <= A[i]) {
number = Math.Max(number, num);
}
}
}
// Erasing from set
s.Remove(number);
// Pushing the elements to vector
maxi.Add(number);
// Keep updating the max
curr_max
= Math.Max(curr_max, maxi[maxi.Count - 1]);
}
Console.Write(
"Lexicographically smallest permutation is : ");
for (int i = 0; i < mini.Count; i++) {
Console.Write(mini[i] + " ");
}
Console.WriteLine("");
Console.Write(
"Lexicographically largest permutation is : ");
for (int i = 0; i < maxi.Count; i++) {
Console.Write(maxi[i] + " ");
}
Console.WriteLine("");
}
static public void Main()
{
// Code
List<int> A = new List<int>() { 2, 4, 4, 4, 6, 6 };
// Function call
findMinMaxPermutation(A);
}
}
// This code is contributed by lokeshmvs21.
// JavaScript code to implement the approach
// Function to return the max array of
// minimum and maximum permutation
// satisfying A
function findMinMaxPermutation(A)
{
let n = A.length;
let s = new Set();
let mini = [];
let maxi = [];
// Pushing all the elements into set till n
for (let i = 1; i < n + 1; i++)
s.add(i);
let curr_max = 0;
for (let i = 0; i < n; i++) {
let number=0;
// If curr_max is less
if (curr_max < A[i]) {
number = A[i];
}
// Choosing the smallest element less than A[i]
else
number = Math.min(...s);
// Erasing from set
s.delete(number);
// Pushing the elements to mini array
mini.push(number);
// Keep updating the max
curr_max = Math.max(curr_max, mini[mini.length-1]);
}
curr_max = 0;
// Pushing all the elements into set till n
for (let i = 1; i < n + 1; i++)
s.add(i);
for (let i = 0; i < n; i++) {
let number=0;
// If curr_max is less
if (curr_max < A[i])
number = A[i];
// Choosing the bigger element but less than A[i]
else
{
for(let num of s)
{
if(num<=A[i])
number=Math.max(number, num);
}
}
// Erasing from set
s.delete(number);
// Pushing the elements to maxi array
maxi.push(number);
// Keep updating the max
curr_max = Math.max(curr_max, maxi[maxi.length-1]);
}
console.log("Lexicographically smallest permutation is : " + mini);
console.log("Lexicographically largest permutation is : " + maxi);
}
// Driver Code
let A = [2, 4, 4, 4, 6, 6 ];
// Function call
findMinMaxPermutation(A);
// This code is contributed by Ishan Khandelwal
Output
Lexicographically smallest permutation is : 2 4 1 3 6 5 Lexicographically largest permutation is : 2 4 3 1 6 5
Time Complexity: N* logN
Auxiliary Space: O(N)