Open In App

Permutation of first N natural numbers having given array as the prefix maximum array

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N positive integers, the task is to find the permutation of first N natural numbers such that the given array arr[] is the prefix maximum array of that permutation. If no such permutation exists, then print “-1”.

Examples:

Input: arr[] = {1, 3, 4, 5, 5}
Output: 1 3 4 5 2
Explanation:
The prefix maximum array of the permutation {1, 3, 4, 5, 2} is {1, 3, 4, 5, 5}.

Input: arr[] = {1, 1, 3, 4}
Output: -1

Naive Approach: The simplest approach to solve the given problem is to generate all possible permutations of the first N natural numbers and check if there exists any permutation whose prefix maximum array is the array arr[] or not. If any such permutation is found, then print that permutation. Otherwise, print “-1”

Time Complexity: O(N * N!)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized based on the observation that the first occurrence of every number in the arr[] will be at the same place as that in the required permutation. Therefore, after filling the first occurrence of all the elements at their correct positions, fill the remaining numbers in ascending order. Follow the steps below to solve the problem:

  • Initialize an array ans[] of size N with all elements as 0 and a vector V[] to store all the unvisited elements in the array.
  • Initialize a HashMap M to store the index of the first occurrence of elements
  • Traverse the array arr[] and if arr[i] is not present in M, then store the index of arr[i] in M and update ans[i] to arr[i].
  • Iterate over the range [1, N] using the variable i and check if i is not present in M, store it in the vector V[].
  • Traverse the array ans[] and if the value of ans[i] is 0, then update ans[i] to V[j] and increment j by 1.
  • After completing the above steps, check if the maximum element prefix array is the same as arr[]. If found to be true, then print the array ans[] as the result. Otherwise, print “-1”.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the maximum
// prefix array of ans[] is equal
// to array arr[]
bool checkPermutation(
    int ans[], int a[], int n)
{
    // Initialize a variable, Max
    int Max = INT_MIN;
 
    // Traverse the array, ans[]
    for (int i = 0; i < n; i++) {
 
        // Store the maximum value
        // upto index i
        Max = max(Max, ans[i]);
 
        // If it is not equal to a[i],
        // then return false
        if (Max != a[i])
            return false;
    }
 
    // Otherwise return false
    return true;
}
 
// Function to find the permutation of
// the array whose prefix maximum array
// is same as the given array a[]
void findPermutation(int a[], int n)
{
    // Stores the required permutation
    int ans[n] = { 0 };
 
    // Stores the index of first
    // occurrence of elements
    unordered_map<int, int> um;
 
    // Traverse the array a[]
    for (int i = 0; i < n; i++) {
 
        // If a[i] is not present
        // in um, then store it in um
        if (um.find(a[i]) == um.end()) {
 
            // Update the ans[i]
            // to a[i]
            ans[i] = a[i];
            um[a[i]] = i;
        }
    }
 
    // Stores the unvisited numbers
    vector<int> v;
    int j = 0;
 
    // Fill the array, v[]
    for (int i = 1; i <= n; i++) {
 
        // Store the index
        if (um.find(i) == um.end()) {
            v.push_back(i);
        }
    }
 
    // Traverse the array, ans[]
    for (int i = 0; i < n; i++) {
 
        // Fill v[j] at places where
        // ans[i] is 0
        if (ans[i] == 0) {
            ans[i] = v[j];
            j++;
        }
    }
 
    // Check if the current permutation
    // maximum prefix array is same as
    // the given array a[]
    if (checkPermutation(ans, a, n)) {
 
        // If true, the print the
        // permutation
        for (int i = 0; i < n; i++) {
            cout << ans[i] << " ";
        }
    }
 
    // Otherwise, print -1
    else
        cout << "-1";
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 3, 4, 5, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    findPermutation(arr, N);
 
    return 0;
}


Java




// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
// Function to check if the maximum
// prefix array of ans[] is equal
// to array arr[]
static boolean checkPermutation(int ans[], int a[],
                                int n)
{
     
    // Initialize a variable, Max
    int Max = Integer.MIN_VALUE;
 
    // Traverse the array, ans[]
    for(int i = 0; i < n; i++)
    {
         
        // Store the maximum value
        // upto index i
        Max = Math.max(Max, ans[i]);
 
        // If it is not equal to a[i],
        // then return false
        if (Max != a[i])
            return false;
    }
 
    // Otherwise return false
    return true;
}
 
// Function to find the permutation of
// the array whose prefix maximum array
// is same as the given array a[]
static void findPermutation(int a[], int n)
{
     
    // Stores the required permutation
    int ans[] = new int[n];
 
    // Stores the index of first
    // occurrence of elements
    HashMap<Integer, Integer> um = new HashMap<>();
 
    // Traverse the array a[]
    for(int i = 0; i < n; i++)
    {
         
        // If a[i] is not present
        // in um, then store it in um
        if (!um.containsKey(a[i]))
        {
             
            // Update the ans[i]
            // to a[i]
            ans[i] = a[i];
            um.put(a[i], i);
        }
    }
 
    // Stores the unvisited numbers
    ArrayList<Integer> v = new ArrayList<>();
    int j = 0;
 
    // Fill the array, v[]
    for(int i = 1; i <= n; i++)
    {
         
        // Store the index
        if (!um.containsKey(i))
        {
            v.add(i);
        }
    }
 
    // Traverse the array, ans[]
    for(int i = 0; i < n; i++)
    {
         
        // Fill v[j] at places where
        // ans[i] is 0
        if (ans[i] == 0)
        {
            ans[i] = v.get(j);
            j++;
        }
    }
 
    // Check if the current permutation
    // maximum prefix array is same as
    // the given array a[]
    if (checkPermutation(ans, a, n))
    {
         
        // If true, the print the
        // permutation
        for(int i = 0; i < n; i++)
        {
            System.out.print(ans[i] + " ");
        }
    }
 
    // Otherwise, print -1
    else
        System.out.println("-1");
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 3, 4, 5, 5 };
    int N = arr.length;
 
    // Function Call
    findPermutation(arr, N);
}
}
 
// This code is contributed by Kingash


Python3




# Python3 program for the above approach
import sys
 
# Function to check if the maximum
# prefix array of ans[] is equal
# to array arr[]
def checkPermutation(ans, a, n):
 
    # Initialize a variable, Max
    Max = -sys.maxsize - 1
 
    # Traverse the array, ans[]
    for i in range(n):
 
        # Store the maximum value
        # upto index i
        Max = max(Max, ans[i])
 
        # If it is not equal to a[i],
        # then return false
        if (Max != a[i]):
            return False
 
    # Otherwise return false
    return True
 
# Function to find the permutation of
# the array whose prefix maximum array
# is same as the given array a[]
def findPermutation(a, n):
 
    # Stores the required permutation
    ans = [0] * n
 
    # Stores the index of first
    # occurrence of elements
    um = {}
 
    # Traverse the array a[]
    for i in range(n):
 
        # If a[i] is not present
        # in um, then store it in um
        if (a[i] not in um):
 
            # Update the ans[i]
            # to a[i]
            ans[i] = a[i]
            um[a[i]] = i
 
    # Stores the unvisited numbers
    v = []
    j = 0
 
    # Fill the array, v[]
    for i in range(1, n + 1):
 
        # Store the index
        if (i not in um):
            v.append(i)
 
    # Traverse the array, ans[]
    for i in range(n):
 
        # Fill v[j] at places where
        # ans[i] is 0
        if (ans[i] == 0):
            ans[i] = v[j]
            j += 1
 
    # Check if the current permutation
    # maximum prefix array is same as
    # the given array a[]
    if (checkPermutation(ans, a, n)):
 
        # If true, the print the
        # permutation
        for i in range(n):
            print(ans[i], end = " ")
 
    # Otherwise, print -1
    else:
        print("-1")
 
# Driver Code
if __name__ == "__main__":
 
    arr = [ 1, 3, 4, 5, 5 ]
    N = len(arr)
 
    # Function Call
    findPermutation(arr, N)
 
# This code is contributed by ukasp


C#




// C# program for the above approach
using System;
using System.Collections.Generic; 
 
class GFG{
     
// Function to check if the maximum
// prefix array of ans[] is equal
// to array arr[]
static bool checkPermutation(int[] ans, int[] a,
                             int n)
{
     
    // Initialize a variable, Max
    int Max = Int32.MinValue;
 
    // Traverse the array, ans[]
    for(int i = 0; i < n; i++)
    {
         
        // Store the maximum value
        // upto index i
        Max = Math.Max(Max, ans[i]);
 
        // If it is not equal to a[i],
        // then return false
        if (Max != a[i])
            return false;
    }
     
    // Otherwise return false
    return true;
}
 
// Function to find the permutation of
// the array whose prefix maximum array
// is same as the given array a[]
static void findPermutation(int[] a, int n)
{
     
    // Stores the required permutation
    int[] ans = new int[n];
 
    // Stores the index of first
    // occurrence of elements
    Dictionary<int,
               int> um = new Dictionary<int,
                                        int>();
 
    // Traverse the array a[]
    for(int i = 0; i < n; i++)
    {
         
        // If a[i] is not present
        // in um, then store it in um
        if (!um.ContainsKey(a[i]))
        {
             
            // Update the ans[i]
            // to a[i]
            ans[i] = a[i];
            um[a[i]] = i;
        }
    }
 
    // Stores the unvisited numbers
    List<int> v = new List<int>();
    int j = 0;
 
    // Fill the array, v[]
    for(int i = 1; i <= n; i++)
    {
         
        // Store the index
        if (!um.ContainsKey(i))
        {
            v.Add(i);
        }
    }
 
    // Traverse the array, ans[]
    for(int i = 0; i < n; i++)
    {
         
        // Fill v[j] at places where
        // ans[i] is 0
        if (ans[i] == 0)
        {
            ans[i] = v[j];
            j++;
        }
    }
 
    // Check if the current permutation
    // maximum prefix array is same as
    // the given array a[]
    if (checkPermutation(ans, a, n))
    {
         
        // If true, the print the
        // permutation
        for(int i = 0; i < n; i++)
        {
            Console.Write(ans[i] + " ");
        }
    }
 
    // Otherwise, print -1
    else
        Console.Write("-1");
}
 
// Driver Code
public static void Main()
{
    int[] arr = { 1, 3, 4, 5, 5 };
    int N = arr.Length;
 
    // Function Call
    findPermutation(arr, N);
}
}
 
// This code is contributed by sanjoy_62


Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to check if the maximum
// prefix array of ans[] is equal
// to array arr[]
function checkPermutation(ans,a,n)
{
    // Initialize a variable, Max
    let Max = Number.MIN_VALUE;
  
    // Traverse the array, ans[]
    for(let i = 0; i < n; i++)
    {
          
        // Store the maximum value
        // upto index i
        Max = Math.max(Max, ans[i]);
  
        // If it is not equal to a[i],
        // then return false
        if (Max != a[i])
            return false;
    }
  
    // Otherwise return false
    return true;
}
 
// Function to find the permutation of
// the array whose prefix maximum array
// is same as the given array a[]
function findPermutation(a,n)
{
    // Stores the required permutation
    let ans = new Array(n);
     for(let i=0;i<n;i++)
    {
        ans[i]=0;
    }
    // Stores the index of first
    // occurrence of elements
    let um = new Map();
  
    // Traverse the array a[]
    for(let i = 0; i < n; i++)
    {
          
        // If a[i] is not present
        // in um, then store it in um
        if (!um.has(a[i]))
        {
              
            // Update the ans[i]
            // to a[i]
            ans[i] = a[i];
            um.set(a[i], i);
        }
    }
  
    // Stores the unvisited numbers
    let v = [];
    let j = 0;
  
    // Fill the array, v[]
    for(let i = 1; i <= n; i++)
    {
          
        // Store the index
        if (!um.has(i))
        {
            v.push(i);
        }
    }
  
    // Traverse the array, ans[]
    for(let i = 0; i < n; i++)
    {
          
        // Fill v[j] at places where
        // ans[i] is 0
        if (ans[i] == 0)
        {
            ans[i] = v[j];
            j++;
        }
    }
  
    // Check if the current permutation
    // maximum prefix array is same as
    // the given array a[]
    if (checkPermutation(ans, a, n))
    {
          
        // If true, the print the
        // permutation
        for(let i = 0; i < n; i++)
        {
            document.write(ans[i] + " ");
        }
    }
  
    // Otherwise, print -1
    else
        document.write("-1");
}
 
// Driver Code
let arr=[1, 3, 4, 5, 5];
let N = arr.length;
// Function Call
findPermutation(arr, N);
 
 
// This code is contributed by avanitrachhadiya2155
 
</script>


Output: 

1 3 4 5 2

 

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



Last Updated : 12 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads