给定一个由N 个正整数组成的数组arr[] ,任务是找到前N 个自然数的排列,使得给定的数组arr[]是该排列的前缀最大数组。如果不存在这样的排列,则打印“-1” 。
例子:
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
朴素方法:解决给定问题的最简单方法是生成前 N 个自然数的所有可能排列,并检查是否存在前缀最大数组为数组arr[] 的任何排列。如果找到任何此类排列,则打印该排列。否则,打印“-1” 。
时间复杂度: O(N * N!)
辅助空间: O(1)
高效的方法:可以根据观察到 arr[] 中每个数字的第一次出现将与所需排列中的数字相同的位置来优化上述方法。因此,在正确位置填充第一次出现的所有元素后,按升序填充剩余的数字。请按照以下步骤解决问题:
- 初始化一个大小为N的数组ans[] ,其中所有元素都为0和一个向量V[]来存储数组中所有未访问的元素。
- 初始化一个 HashMap M来存储元素第一次出现的索引
- 遍历数组arr[]并且如果arr[i]不存在于M 中,则将arr[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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live