Given three integers N, A, and B, the task is to find a permutation of pairwise distinct numbers from 1 to N such that A is the minimum element of the left half and B is the maximum element of the right half. It is also given that N is even. If no such permutations exist print -1.
Examples:
Input: N = 6, A = 2, B = 5
Output: 6, 2, 4, 3, 5, 1
Explanation: A = 2 is the minima of the left half.
B = 5 is the maxima of the right half.Input: N = 6, A = 1, B = 3
Output: -1
Explanation: No such permutation exists.
Naive Approach (Brute Force): In this approach, generate all permutations of 1 to N numbers and check each one individually. Follow the below steps, to solve this problem:
- Generate all the permutations of numbers from 1 to N and store them in an array.
- Traverse through each permutation, if in the following permutation A is the minima of the left half and B is the maxima of the right half then print the permutation.
- If no such permutation exists, then print -1.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to generate next permutation void nextPermutation(vector< int >& nums)
{ int n = nums.size(), k, l;
for (k = n - 2; k >= 0; k--) {
if (nums[k] < nums[k + 1]) {
break ;
}
}
if (k < 0) {
reverse(nums.begin(), nums.end());
}
else {
for (l = n - 1; l > k; l--) {
if (nums[l] > nums[k]) {
break ;
}
}
swap(nums[k], nums[l]);
reverse(nums.begin() + k + 1, nums.end());
}
} // Factorial function int factorial( int n)
{ return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
} // Function to returns all the permutations // of a given array or vector vector<vector< int > > permute(vector< int >& nums)
{ vector<vector< int > > permuted;
int n = nums.size();
int factn = factorial(n);
for ( int i = 0; i < factn; i++) {
permuted.push_back(nums);
nextPermutation(nums);
}
return permuted;
} // Function to find the permutation // of 1 to N numbers // having A minimas and B maximas void findPermutation( int n, int a, int b)
{ // Generate the array
// containing one permutation
vector< int > nums(n);
for ( int i = 0; i < n; i++) {
nums[i] = i + 1;
}
// Generate all the permutations
vector<vector< int > > allpermutations = permute(nums);
int total = allpermutations.size();
int ansindex = -1;
for ( int i = 0; i < total; i++) {
// Find the minima of the left half
// maxima of the right half
int leftmin = allpermutations[i][0];
int rightmax = allpermutations[i][n - 1];
for ( int j = 0; j < n / 2; j++) {
if (allpermutations[i][j] < leftmin) {
leftmin = allpermutations[i][j];
}
}
for ( int j = n / 2; j < n; j++) {
if (allpermutations[i][j] > rightmax) {
rightmax = allpermutations[i][j];
}
}
if (leftmin == a && rightmax == b) {
// Store the index
// of a perfect permutation
ansindex = i;
break ;
}
}
// Print -1 if no such permutation exists
if (ansindex == -1) {
cout << -1;
}
else {
// Print the perfect permutation if exists
for ( int i = 0; i < n; i++) {
cout << allpermutations[ansindex][i] << " " ;
}
}
} // Driver Code int main()
{ int N = 6, A = 2, B = 5;
findPermutation(N, A, B);
return 0;
} |
// Java program for the above approach import java.util.*;
public class GFG {
// Function to generate next permutation
static void nextPermutation( int [] nums)
{
int n = nums.length, k, l;
for (k = n - 2 ; k >= 0 ; k--) {
if (nums[k] < nums[k + 1 ]) {
break ;
}
}
if (k < 0 ) {
reverse(nums, 0 , n - 1 );
}
else {
for (l = n - 1 ; l > k; l--) {
if (nums[l] > nums[k]) {
break ;
}
}
// swap(nums[k], nums[l]);
int t = nums[k];
nums[k] = nums[l];
nums[l] = t;
reverse(nums, k + 1 , n - 1 );
}
}
static void reverse( int [] nums, int l, int r)
{
while (l < r) {
// swap
int t = nums[l];
nums[l] = nums[r];
nums[r] = t;
l++;
r--;
}
}
// Factorial function
static int factorial( int n)
{
return (n == 1 || n == 0 ) ? 1
: factorial(n - 1 ) * n;
}
// Function to returns all the permutations
// of a given array or vector
static int [][] permute( int [] nums)
{
int n = nums.length;
int factn = factorial(n);
int [][] permuted = new int [factn][n];
for ( int i = 0 ; i < factn; i++) {
permuted[i] = nums.clone();
nextPermutation(nums);
}
return permuted;
}
// Function to find the permutation
// of 1 to N numbers
// having A minimas and B maximas
static void findPermutation( int n, int a, int b)
{
// Generate the array
// containing one permutation
int [] nums = new int [n];
for ( int i = 0 ; i < n; i++) {
nums[i] = i + 1 ;
}
// Generate all the permutations
int [][] allpermutations = permute(nums);
int total = allpermutations.length;
int ansindex = - 1 ;
for ( int i = 0 ; i < total; i++) {
// Find the minima of the left half
// maxima of the right half
int leftmin = allpermutations[i][ 0 ];
int rightmax = allpermutations[i][n - 1 ];
for ( int j = 0 ; j < n / 2 ; j++) {
if (allpermutations[i][j] < leftmin) {
leftmin = allpermutations[i][j];
}
}
for ( int j = n / 2 ; j < n; j++) {
if (allpermutations[i][j] > rightmax) {
rightmax = allpermutations[i][j];
}
}
if (leftmin == a && rightmax == b) {
// Store the index
// of a perfect permutation
ansindex = i;
break ;
}
}
// Print -1 if no such permutation exists
if (ansindex == - 1 ) {
System.out.print(- 1 );
}
else {
// Print the perfect permutation if exists
for ( int i = 0 ; i < n; i++) {
System.out.print(
allpermutations[ansindex][i] + " " );
}
}
}
// Driver Code
public static void main(String[] args)
{
int N = 6 , A = 2 , B = 5 ;
findPermutation(N, A, B);
}
} // This code is contributed by karandeep1234 |
# Python code to implement the above approach num = []
# Function to generate next permutation def nextPermutation(nums):
global num
n = len (nums)
for k in range (n - 2 , - 1 , - 1 ):
if (nums[k] < nums[k + 1 ]):
break
if (k < 0 ):
nums.reverse()
else :
for l in range (n - 1 , k, - 1 ):
if (nums[l] > nums[k]):
break
nums[k], nums[l] = nums[l], nums[k]
temp = nums[k + 1 :]
temp.reverse()
nums = nums[:k + 1 ] + temp
return nums
# Factorial function def factorial(n):
return 1 if (n = = 1 or n = = 0 ) else factorial(n - 1 ) * n
# Function to returns all the permutations # of a given array or vector def permute(nums):
global num
permuted = []
n = len (nums)
factn = factorial(n)
for i in range (factn):
permuted.append(nums)
nums = nextPermutation(nums)
permuted.append(nums)
return permuted
# Function to find the permutation # of 1 to N numbers # having A minimas and B maximas def findPermutation(n, a, b):
# Generate the array
# containing one permutation
nums = [ 0 ] * n
for i in range (n):
nums[i] = i + 1
# Generate all the permutations
allpermutations = permute(nums)
total = len (allpermutations)
ansindex = - 1
for i in range (total):
# Find the minima of the left half
# maxima of the right half
leftmin = allpermutations[i][ 0 ]
rightmax = allpermutations[i][n - 1 ]
for j in range (n / / 2 ):
if (allpermutations[i][j] < leftmin):
leftmin = allpermutations[i][j]
for j in range (n / / 2 , n):
if (allpermutations[i][j] > rightmax):
rightmax = allpermutations[i][j]
if (leftmin = = a and rightmax = = b):
# Store the index
# of a perfect permutation
ansindex = i
break
# Pr-1 if no such permutation exists
if (ansindex = = - 1 ):
print ( - 1 )
else :
# Print the perfect permutation if exists
for i in range (n):
print (allpermutations[ansindex][i], end = " " )
# Driver Code N = 6
A = 2
B = 5
findPermutation(N, A, B) # This code is contributed by Shubham Singh |
<script> class GFG { // Function to generate next permutation
static nextPermutation(nums)
{
var n = nums.length;
var k = 0;
var l = 0;
for (k = n - 2; k >= 0; k--)
{
if (nums[k] < nums[k + 1])
{
break ;
}
}
if (k < 0)
{
GFG.reverse(nums, 0, n - 1);
}
else
{
for (l = n - 1; l > k; l--)
{
if (nums[l] > nums[k])
{
break ;
}
}
// swap(nums[k], nums[l]);
var t = nums[k];
nums[k] = nums[l];
nums[l] = t;
GFG.reverse(nums, k + 1, n - 1);
}
}
static reverse(nums, l, r)
{
while (l < r)
{
// swap
var t = nums[l];
nums[l] = nums[r];
nums[r] = t;
l++;
r--;
}
}
// Factorial function
static factorial(n)
{
return (n == 1 || n == 0) ? 1 : GFG.factorial(n - 1) * n;
}
// Function to returns all the permutations
// of a given array or vector
static permute(nums)
{
var n = nums.length;
var factn = GFG.factorial(n);
var permuted = Array(factn).fill(0).map(()=> new Array(n).fill(0));
for (let i=0; i < factn; i++)
{
permuted[i] = [...nums];
GFG.nextPermutation(nums);
}
return permuted;
}
// Function to find the permutation
// of 1 to N numbers
// having A minimas and B maximas
static findPermutation(n, a, b)
{
// Generate the array
// containing one permutation
var nums = Array(n).fill(0);
for (let i=0; i < n; i++)
{
nums[i] = i + 1;
}
// Generate all the permutations
var allpermutations = GFG.permute(nums);
var total = allpermutations.length;
var ansindex = -1;
for (let i=0; i < total; i++)
{
// Find the minima of the left half
// maxima of the right half
var leftmin = allpermutations[i][0];
var rightmax = allpermutations[i][n - 1];
for (let j=0; j < parseInt(n / 2); j++)
{
if (allpermutations[i][j] < leftmin)
{
leftmin = allpermutations[i][j];
}
}
for (let j=n/2; j < n; j++)
{
if (allpermutations[i][j] > rightmax)
{
rightmax = allpermutations[i][j];
}
}
if (leftmin == a && rightmax == b)
{
// Store the index
// of a perfect permutation
ansindex = i;
break ;
}
}
// Print -1 if no such permutation exists
if (ansindex == -1)
{
console.log(-1);
}
else
{
// Print the perfect permutation if exists
for (let i=0; i < n; i++)
{
document.write(allpermutations[ansindex][i] + " " );
}
}
}
// Driver Code
static main(args)
{
var N = 6;
var A = 2;
var B = 5;
GFG.findPermutation(N, A, B);
}
} GFG.main([]); </script> |
// C# program for the above approach using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static void Main( string [] args)
{
int N = 6, A = 2, B = 5;
FindPermutation(N, A, B);
}
// Function to find the permutation
// of 1 to N numbers
// having A minimas and B maximas
static void FindPermutation( int n, int a, int b)
{
// Generate the array containing one permutation
var nums = Enumerable.Range(1, n).ToList();
// Generate all the permutations
var allPermutations = Permute(nums);
var total = allPermutations.Count;
var ansIndex = -1;
for ( var i = 0; i < total; i++) {
// Find the minima of the left half
// maxima of the right half
var leftMin = allPermutations[i][0];
var rightMax = allPermutations[i][n - 1];
for ( var j = 0; j < n / 2; j++) {
if (allPermutations[i][j] < leftMin) {
leftMin = allPermutations[i][j];
}
}
for ( var j = n / 2; j < n; j++) {
if (allPermutations[i][j] > rightMax) {
rightMax = allPermutations[i][j];
}
}
if (leftMin == a && rightMax == b) {
// Store the index of a perfect permutation
ansIndex = i;
break ;
}
}
// Print -1 if no such permutation exists
if (ansIndex == -1) {
Console.WriteLine(-1);
}
else {
// Print the perfect permutation if exists
for ( var i = 0; i < n; i++) {
Console.Write(allPermutations[ansIndex][i]
+ " " );
}
}
}
// Function to returns all the permutations
// of a given array or vector
static List<List< int > > Permute(List< int > nums)
{
var permuted = new List<List< int > >();
var n = nums.Count;
var factN = Factorial(n);
for ( var i = 0; i < factN; i++) {
permuted.Add(nums.ToList());
NextPermutation(nums);
}
return permuted;
}
// Factorial function
static int Factorial( int n)
{
return (n == 1 || n == 0) ? 1
: Factorial(n - 1) * n;
}
// Function to generate next permutation
static void NextPermutation(List< int > nums)
{
var n = nums.Count;
int k, l;
for (k = n - 2; k >= 0; k--) {
if (nums[k] < nums[k + 1]) {
break ;
}
}
if (k < 0) {
nums.Reverse();
}
else {
for (l = n - 1; l > k; l--) {
if (nums[l] > nums[k]) {
break ;
}
}
var temp = nums[k];
nums[k] = nums[l];
nums[l] = temp;
var start = k + 1;
var end = n - 1;
while (start < end) {
temp = nums[start];
nums[start++] = nums[end];
nums[end--] = temp;
}
}
}
} |
2 3 6 1 4 5
Time Complexity: O(N!)
Auxiliary Space: O(N!)
Efficient Approach (Greedy Method): The above brute force method can be optimized using the Greedy Algorithm. Greedy is an algorithmic paradigm that builds up a solution piece by piece, always choosing the next piece that offers the most obvious and immediate benefit. So, break the problem into different usable pieces according to the values of N, A, B. Follow the below steps to solve this problem:
- Initialize the variables left as n-b and right as a-1.
- If left or right is greater than n/2 then print -1
- Else if a and b are less than equal to n/2 then print -1.
- Else if a and b are greater than n/2 then print -1.
- Else if a equals n/2+1 and b equals n/2 then print n to 1 as the answer.
- Else, iterate over the range [0, n) using the variable i and perform the following tasks:
- If n-i equals a or b then print a or b else print n-i.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to get the desired permutation void getpermutation( int n, int a, int b)
{ int left = n - b, right = a - 1;
// When b < n/2 or a > n/2
if (left > n / 2 || right > n / 2) {
cout << -1;
}
// When a and b both are
// in the same half
else if (a <= n / 2 && b <= n / 2) {
cout << -1;
}
else if (a > n / 2 && b > n / 2) {
cout << -1;
}
// The corner case
else if (a == n / 2 + 1 && b == n / 2) {
for ( int i = 0; i < n; i++) {
cout << n - i << " " ;
}
}
// Rest other combinations
else {
for ( int i = 0; i < n; i++) {
if (n - i == b) {
cout << a << " " ;
}
else if (n - i == a) {
cout << b << " " ;
}
else {
cout << n - i << " " ;
}
}
}
cout << endl;
} // Driver Code int main()
{ int N = 6, A = 2, B = 5;
getpermutation(N, A, B);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG {
// Function to get the desired permutation
static void getpermutation( int n, int a, int b)
{
int left = n - b, right = a - 1 ;
// When b < n/2 or a > n/2
if (left > n / 2 || right > n / 2 ) {
System.out.print(- 1 );
}
// When a and b both are
// in the same half
else if (a <= n / 2 && b <= n / 2 ) {
System.out.print(- 1 );
}
else if (a > n / 2 && b > n / 2 ) {
System.out.print(- 1 );
}
// The corner case
else if (a == n / 2 + 1 && b == n / 2 ) {
for ( int i = 0 ; i < n; i++) {
System.out.print(n - i + " " );
}
}
// Rest other combinations
else {
for ( int i = 0 ; i < n; i++) {
if (n - i == b) {
System.out.print(a + " " );
}
else if (n - i == a) {
System.out.print(b + " " );
}
else {
System.out.print(n - i + " " );
}
}
}
System.out.println();
}
// Driver Code
public static void main(String args[])
{
int N = 6 , A = 2 , B = 5 ;
getpermutation(N, A, B);
}
} // This code is contributed by Samim Hossain Mondal. |
# python program for the above approach # Function to get the desired permutation def getpermutation(n, a, b):
left = n - b
right = a - 1
# When b < n/2 or a > n/2
if (left > n / 2 or right > n / 2 ):
print ( - 1 )
# When a and b both are
# in the same half
elif (a < = n / 2 and b < = n / 2 ):
print ( - 1 )
elif (a > n / 2 and b > n / 2 ):
print ( - 1 )
# The corner case
elif (a = = n / 2 + 1 and b = = n / 2 ):
for i in range ( 0 , n):
print (n - i, end = " " )
# Rest other combinations
else :
for i in range ( 0 , n):
if (n - i = = b):
print (a, end = " " )
elif (n - i = = a):
print (b, end = " " )
else :
print (n - i, end = " " )
print ()
# Driver Code if __name__ = = "__main__" :
N = 6
A = 2
B = 5
getpermutation(N, A, B)
# This code is contributed by rakeshsahni
|
// C# program for the above approach using System;
class GFG {
// Function to get the desired permutation
static void getpermutation( int n, int a, int b)
{
int left = n - b, right = a - 1;
// When b < n/2 or a > n/2
if (left > n / 2 || right > n / 2) {
Console.Write(-1);
}
// When a and b both are
// in the same half
else if (a <= n / 2 && b <= n / 2) {
Console.Write(-1);
}
else if (a > n / 2 && b > n / 2) {
Console.Write(-1);
}
// The corner case
else if (a == n / 2 + 1 && b == n / 2) {
for ( int i = 0; i < n; i++) {
Console.Write(n - i + " " );
}
}
// Rest other combinations
else {
for ( int i = 0; i < n; i++) {
if (n - i == b) {
Console.Write(a + " " );
}
else if (n - i == a) {
Console.Write(b + " " );
}
else {
Console.Write(n - i + " " );
}
}
}
Console.WriteLine();
}
// Driver Code
public static void Main()
{
int N = 6, A = 2, B = 5;
getpermutation(N, A, B);
}
} // This code is contributed by ukasp. |
<script> // JavaScript code for the above approach
// Function to get the desired permutation
function getpermutation(n, a, b) {
let left = n - b, right = a - 1;
// When b < n/2 or a > n/2
if (left > Math.floor(n / 2) || right > Math.floor(n / 2)) {
document.write(-1 + " " );
}
// When a and b both are
// in the same half
else if (a <= Math.floor(n / 2) && b <= Math.floor(n / 2)) {
document.write(-1 + " " );
}
else if (a > Math.floor(n / 2) && b > Math.floor(n / 2)) {
document.write(-1 + " " );
}
// The corner case
else if (a == Math.floor(n / 2) + 1 && b == Math.floor(n / 2)) {
for (let i = 0; i < n; i++) {
document.write(n - i + " " );
}
}
// Rest other combinations
else {
for (let i = 0; i < n; i++) {
if (n - i == b) {
document.write(a + " " )
}
else if (n - i == a) {
document.write(b + " " )
}
else {
document.write(n - i + " " )
}
}
}
cout << endl;
}
// Driver Code
let N = 6, A = 2, B = 5;
getpermutation(N, A, B);
// This code is contributed by Potta Lokesh
</script>
|
6 2 4 3 5 1
Time Complexity: O(N)
Auxiliary Space: O(1) as constant space for variables has been used