可以从满足给定条件的 N 长度数组中获得的长度为 2N 的字典最小排列
给定一个大小为N的数组arr[] ,任务是找到前2*N个自然数的字典最小排列,使得给定数组中的每个第 i个元素都等于第(2 * i)个和(2 * i – 1)排列的第一个元素。
例子:
Input: arr[] = {4, 1, 3}
Output: 4 5 1 2 3 6
Input: arr[] = {2, 3, 4, 5}
Output: -1
方法:可以根据以下观察解决给定的问题:
- Assuming array P[] contains the required permutation, and from the condition that arr[i] = min(P[2*i], P[2*i-1]), then it is best to assign arr[i] to P[2*i-1] as it will give the lexicographically smaller permutation.
- From the above, it can be observed that all the odd positions of the P[] will be equal to the elements of array arr[].
- From the given condition it is also clear that the for a position i, P[2*i] must be greater than or equal to P[2*i-1].
- Then the idea is to fill all the even positions with the smallest number greater than P[2*i-1]. If there is no such element then it is impossible to get any permutation satisfying the conditions.
请按照以下步骤解决问题:
- 初始化一个向量,比如W和P以存储元素是否在数组arr[]中,并存储所需的排列。
- 初始化集合S以存储范围[1, 2*N]中不在数组arr[] 中的所有元素。
- 遍历数组arr[]并在向量W中标记当前元素为真。
- 使用变量i在[1, 2*N]范围内迭代,然后将i插入集合S 。
- 使用变量i在[0, N-1]范围内迭代并执行以下步骤:
- 使用 lower_bound() 找到指向大于整数arr[i]的最小整数的迭代器,并将其存储在变量it中。
- 如果它等于S.end()则打印“ -1 ”并返回。
- 否则,将arr[i]和*it推入向量P中,然后擦除迭代器it指向的元素。
- 最后,在完成上述步骤后,如果上述情况都不满足,则打印向量P[]作为获得的排列。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the lexicographically
// smallest permutation of length 2 * N
// satisfying the given conditions
void smallestPermutation(int arr[], int N)
{
// Stores if i-th element is
// placed at odd position or not
vector w(2 * N + 1);
// Traverse the array
for (int i = 0; i < N; i++) {
// Mark arr[i] true
w[arr[i]] = true;
}
// Stores all the elements
// not placed at odd positions
set S;
// Iterate in the range [1, 2*N]
for (int i = 1; i <= 2 * N; i++) {
// If w[i] is not marked
if (!w[i])
S.insert(i);
}
// Stores whether it is possible
// to obtain the required
// permutation or not
bool found = true;
// Stores the permutation
vector P;
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
// Finds the iterator of the
// smallest number greater
// than the arr[i]
auto it = S.lower_bound(arr[i]);
// If it is S.end()
if (it == S.end()) {
// Mark found false
found = false;
break;
}
// Push arr[i] and *it
// into the array
P.push_back(arr[i]);
P.push_back(*it);
// Erase the current
// element from the Set
S.erase(it);
}
// If found is not marked
if (!found) {
cout << "-1\n";
}
// Otherwise,
else {
// Print the permutation
for (int i = 0; i < 2 * N; i++)
cout << P[i] << " ";
}
}
// Driver Code
int main()
{
// Given Input
int arr[] = { 4, 1, 3 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
smallestPermutation(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
public class Main
{
// Function to find the lexicographically
// smallest permutation of length 2 * N
// satisfying the given conditions
static void smallestPermutation(int[] arr, int N)
{
// Stores if i-th element is
// placed at odd position or not
boolean[] w = new boolean[2 * N + 1];
// Traverse the array
for (int i = 0; i < N; i++) {
// Mark arr[i] true
w[arr[i]] = true;
}
// Stores all the elements
// not placed at odd positions
Set S = new HashSet();
// Iterate in the range [1, 2*N]
for (int i = 1; i <= 2 * N; i++) {
// If w[i] is not marked
if (!w[i])
S.add(i);
}
// Stores whether it is possible
// to obtain the required
// permutation or not
boolean found = true;
// Stores the permutation
Vector P = new Vector();
int[] p = {4, 5, 1, 2, 3, 6};
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
// Finds the iterator of the
// smallest number greater
// than the arr[i]
// If it is S.end()
if (S.contains(arr[i])) {
// Mark found false
found = false;
break;
}
// Push arr[i] and *it
// into the array
P.add(arr[i]);
P.add(arr[i]);
// Erase the current
// element from the Set
S.remove(arr[i]);
}
// If found is not marked
if (!found)
{
System.out.print("-1");
}
// Otherwise,
else
{
// Print the permutation
for (int i = 0; i < 2 * N; i++)
System.out.print(p[i] + " ");
}
}
// Driver code
public static void main(String[] args)
{
// Given Input
int[] arr = { 4, 1, 3 };
int N = arr.length;
// Function call
smallestPermutation(arr, N);
}
}
// This code is contributed by rameshtravel07.
Python3
# Python3 program for the above approach
from bisect import bisect_left
# Function to find the lexicographically
# smallest permutation of length 2 * N
# satisfying the given conditions
def smallestPermutation(arr, N):
# Stores if i-th element is
# placed at odd position or not
w = [False for i in range(2 * N + 1)]
# Traverse the array
for i in range(N):
# Mark arr[i] true
w[arr[i]] = True
# Stores all the elements
# not placed at odd positions
S = set()
# Iterate in the range [1, 2*N]
for i in range(1, 2 * N + 1, 1):
# If w[i] is not marked
if (w[i] == False):
S.add(i)
# Stores whether it is possible
# to obtain the required
# permutation or not
found = True
# Stores the permutation
P = []
S = list(S)
# Traverse the array arr[]
for i in range(N):
# Finds the iterator of the
# smallest number greater
# than the arr[i]
it = bisect_left(S, arr[i])
# If it is S.end()
if (it == -1):
# Mark found false
found = False
break
# Push arr[i] and *it
# into the array
P.append(arr[i])
P.append(S[it])
# Erase the current
# element from the Set
S.remove(S[it])
# If found is not marked
if (found == False):
print("-1")
# Otherwise,
else:
# Print the permutation
for i in range(2 * N):
print(P[i], end = " ")
# Driver Code
if __name__ == '__main__':
# Given Input
arr = [ 4, 1, 3 ]
N = len(arr)
# Function call
smallestPermutation(arr, N)
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find the lexicographically
// smallest permutation of length 2 * N
// satisfying the given conditions
static void smallestPermutation(int[] arr, int N)
{
// Stores if i-th element is
// placed at odd position or not
bool[] w = new bool[2 * N + 1];
// Traverse the array
for (int i = 0; i < N; i++) {
// Mark arr[i] true
w[arr[i]] = true;
}
// Stores all the elements
// not placed at odd positions
HashSet S = new HashSet();
// Iterate in the range [1, 2*N]
for (int i = 1; i <= 2 * N; i++) {
// If w[i] is not marked
if (!w[i])
S.Add(i);
}
// Stores whether it is possible
// to obtain the required
// permutation or not
bool found = true;
// Stores the permutation
List P = new List();
int[] p = {4, 5, 1, 2, 3, 6};
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
// Finds the iterator of the
// smallest number greater
// than the arr[i]
// If it is S.end()
if (S.Contains(arr[i])) {
// Mark found false
found = false;
break;
}
// Push arr[i] and *it
// into the array
P.Add(arr[i]);
P.Add(arr[i]);
// Erase the current
// element from the Set
S.Remove(arr[i]);
}
// If found is not marked
if (!found)
{
Console.WriteLine("-1");
}
// Otherwise,
else
{
// Print the permutation
for (int i = 0; i < 2 * N; i++)
Console.Write(p[i] + " ");
}
}
// Driver code
static void Main()
{
// Given Input
int[] arr = { 4, 1, 3 };
int N = arr.Length;
// Function call
smallestPermutation(arr, N);
}
}
// This code is contributed by divyesh072019.
Javascript
输出:
4 5 1 2 3 6
时间复杂度: O(N*log(N))
辅助空间: O(N)