Given an array arr[] of length N, the task is to check if it can be formed by merging two permutations of the same or different lengths. Print YES if such merging is possible. Otherwise, print NO.
Permutations of length 3 are {1, 2, 3}, {2, 3, 1}, {1, 3, 2}, {3, 1, 2}, {3, 2, 1}, {2, 1, 3}.
Examples:
Input: arr = [1, 3, 2, 4, 3, 1, 2]
Output: YES
Explanation:
The given array can be formed by merging a permutation of length 4 [1, 3, 2, 4] and permutation of length 3 [3, 1, 2]
Input: arr = [1, 2, 3, 2, 3, 2, 1]
Output: NO
Approach :
We can observe that the minimum excludant (MEX) of a permutation of length N is N+1.
So, if the length of the first permutation is l, then MEX of the prefix arr [0 …… l-1] is l+1 and the MEX of the suffix a[l …… n] will be N – l + 1.
So, we can calculate MEX of prefix and suffixes and if the above condition is satisfied, the answer will be “YES”. Otherwise, the answer will be “NO”.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
void if_merged_permutations( int a[],
int n)
{
int pre_mex[n];
int freq[n + 1];
memset (freq, 0, sizeof (freq));
for ( int i = 0; i < n; i++)
{
pre_mex[i] = 1;
}
int mex = 1;
for ( int i = 0; i < n; i++)
{
freq[a[i]]++;
if (freq[a[i]] > 1)
{
break ;
}
if (a[i] == mex)
{
while (freq[mex] != 0)
{
mex++;
}
}
pre_mex[i] = mex;
}
int suf_mex[n];
for ( int i = 0; i < n; i++)
{
suf_mex[i] = 1;
}
memset (freq, 0, sizeof (freq));
mex = 1;
for ( int i = n - 1; i > -1; i--)
{
freq[a[i]]++;
if (freq[a[i]] > 1)
{
continue ;
}
if (a[i] == mex)
{
while (freq[mex] != 0)
{
mex++;
}
}
suf_mex[i] = mex;
}
for ( int i = 0; i < n - 1; i++)
{
if (pre_mex[i] == i + 2 &&
suf_mex[i + 1] == n - i)
{
cout << "YES" << endl;
return ;
}
}
cout << "NO" << endl;
}
int main()
{
int a[] = {1, 3, 2,
4, 3, 1, 2};
int n = sizeof (a)/ sizeof (a[0]);
if_merged_permutations(a, n);
}
|
Java
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG{
static void if_merged_permutations( int a[],
int n)
{
int [] pre_mex = new int [n];
int [] freq = new int [n + 1 ];
for ( int i = 0 ; i < n; i++)
{
pre_mex[i] = 1 ;
}
int mex = 1 ;
for ( int i = 0 ; i < n; i++)
{
freq[a[i]]++;
if (freq[a[i]] > 1 )
{
break ;
}
if (a[i] == mex)
{
while (freq[mex] != 0 )
{
mex++;
}
}
pre_mex[i] = mex;
}
int [] suf_mex = new int [n];
for ( int i = 0 ; i < n; i++)
{
suf_mex[i] = 1 ;
}
Arrays.fill(freq, 0 );
mex = 1 ;
for ( int i = n - 1 ; i > - 1 ; i--)
{
freq[a[i]]++;
if (freq[a[i]] > 1 )
{
continue ;
}
if (a[i] == mex)
{
while (freq[mex] != 0 )
{
mex++;
}
}
suf_mex[i] = mex;
}
for ( int i = 0 ; i < n - 1 ; i++)
{
if (pre_mex[i] == i + 2 &&
suf_mex[i + 1 ] == n - i)
{
System.out.println( "YES" );
return ;
}
}
System.out.println( "NO" );
}
public static void main(String[] args)
{
int a[] = { 1 , 3 , 2 , 4 , 3 , 1 , 2 };
int n = a.length;
if_merged_permutations(a, n);
}
}
|
Python3
def if_merged_permutations(a, n):
pre_mex = [ 1 for i in range (n)]
freq = [ 0 for i in range (n + 1 )]
mex = 1
for i in range (n):
freq[a[i]] + = 1
if freq[a[i]]> 1 :
break
if a[i] = = mex:
while freq[mex]! = 0 :
mex + = 1
pre_mex[i] = mex
suf_mex = [ 1 for i in range (n)]
freq = [ 0 for i in range (n + 1 )]
mex = 1
for i in range (n - 1 , - 1 , - 1 ):
freq[a[i]] + = 1
if freq[a[i]]> 1 :
break
if a[i] = = mex:
while freq[mex]! = 0 :
mex + = 1
suf_mex[i] = mex
for i in range (n - 1 ):
if pre_mex[i] = = i + 2 and suf_mex[i + 1 ] = = n - i:
print ( "YES" )
return
print ( "NO" )
a = [ 1 , 3 , 2 , 4 , 3 , 1 , 2 ]
n = len (a)
if_merged_permutations(a, n)
|
C#
using System;
class GFG{
static void if_merged_permutations( int [] a,
int n)
{
int [] pre_mex = new int [n];
int [] freq = new int [n + 1];
for ( int i = 0; i < n; i++)
{
pre_mex[i] = 1;
}
int mex = 1;
for ( int i = 0; i < n; i++)
{
freq[a[i]]++;
if (freq[a[i]] > 1)
{
break ;
}
if (a[i] == mex)
{
while (freq[mex] != 0)
{
mex++;
}
}
pre_mex[i] = mex;
}
int [] suf_mex = new int [n];
for ( int i = 0; i < n; i++)
{
suf_mex[i] = 1;
}
Array.Fill(freq, 0);
mex = 1;
for ( int i = n - 1; i > -1; i--)
{
freq[a[i]]++;
if (freq[a[i]] > 1)
{
continue ;
}
if (a[i] == mex)
{
while (freq[mex] != 0)
{
mex++;
}
}
suf_mex[i] = mex;
}
for ( int i = 0; i < n - 1; i++)
{
if (pre_mex[i] == i + 2 &&
suf_mex[i + 1] == n - i)
{
Console.WriteLine( "YES" );
return ;
}
}
Console.WriteLine( "NO" );
}
static void Main()
{
int [] a = { 1, 3, 2, 4, 3, 1, 2 };
int n = a.Length;
if_merged_permutations(a, n);
}
}
|
Javascript
<script>
function if_merged_permutations(a, n)
{
var pre_mex = Array(n).fill(0);
var freq = Array(n+1).fill(0);
for ( var i = 0; i < n; i++)
{
pre_mex[i] = 1;
}
var mex = 1;
for ( var i = 0; i < n; i++)
{
freq[a[i]]++;
if (freq[a[i]] > 1)
{
break ;
}
if (a[i] == mex)
{
while (freq[mex] != 0)
{
mex++;
}
}
pre_mex[i] = mex;
}
var suf_mex = Array(n).fill(0);;
for ( var i = 0; i < n; i++)
{
suf_mex[i] = 1;
}
freq = Array(n).fill(0);
mex = 1;
for ( var i = n - 1; i > -1; i--)
{
freq[a[i]]++;
if (freq[a[i]] > 1)
{
continue ;
}
if (a[i] == mex)
{
while (freq[mex] != 0)
{
mex++;
}
}
suf_mex[i] = mex;
}
for ( var i = 0; i < n - 1; i++)
{
if (pre_mex[i] == i + 2 &&
suf_mex[i + 1] == n - i)
{
document.write( "YES" );
return ;
}
}
document.write( "NO" );
}
var a = [1, 3, 2, 4, 3, 1, 2];
var n = a.length;
if_merged_permutations(a, n);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N) since using extra space for array freq