给定一个由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,则改编[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)