📌  相关文章
📜  给定数组作为前缀最大数组的前N个自然数的置换

📅  最后修改于: 2021-04-17 18:38:41             🧑  作者: Mango

给定一个由N个正整数组成的数组arr [] ,任务是查找前N个自然数的排列,以使给定的数组arr []是该排列的前缀最大数组。如果不存在这样的排列,则打印“ -1”

例子:

天真的方法:解决给定问题的最简单方法是生成前N个自然数的所有可能置换,并检查是否存在其前缀最大数组为数组arr []的置换。如果找到任何这样的排列,则打印该排列。否则,打印“ -1”

时间复杂度: O(N * N!)
辅助空间: O(1)

高效的方法:可以基于以下观察来优化上述方法 arr []中每个数字的首次出现将与所需排列的出现在相同的位置。因此,在所有元素的正确位置首次出现后,请按升序填充其余数字。请按照以下步骤解决问题:

  • 初始化大小为N的数组ans [] ,将所有元素都设置为0,并使用向量V []来存储数组中所有未访问的元素。
  • 初始化HashMap M以存储第一次出现的元素的索引
  • 遍历数组ARR [],并且如果ARR [i]是不存在于M,改编[I]的索引存储在M和更新ANS [I]Arr [i]中
  • 使用变量i遍历[1,N]的范围并检查i是否不存在于M中,并将其存储在向量V []中
  • 遍历数组ans [] ,如果ans [i]的值为0 ,则将ans [i]更新为V [j]并使j增加1
  • 完成上述步骤后,检查最大元素前缀数组是否与arr []相同。如果发现为真,则将数组ans []打印为结果。否则,打印“ -1”

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
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 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 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);
        }
    }
 
    // Travere 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 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 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);
        }
    }
 
    // Travere 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)
 
    # Travere 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 um = new Dictionary();
 
    // 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 v = new List();
    int j = 0;
 
    // Fill the array, v[]
    for(int i = 1; i <= n; i++)
    {
         
        // Store the index
        if (!um.ContainsKey(i))
        {
            v.Add(i);
        }
    }
 
    // Travere 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


输出:
1 3 4 5 2

时间复杂度: O(N)
辅助空间: O(N)