Find a permutation of 1 to N, such that A is minimum in left half and B is maximum in right half
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++
// 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
// 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 |
Python3
# 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 |
Javascript
<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#
// 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++
// 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
// 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. |
Python3
# 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#
// 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. |
Javascript
<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
Please Login to comment...