Find a permutation of 1 to N, such that A is minimum in left half and B is maximum in right half - GeeksforGeeks

28 Jan, 2022
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 = 5Output: 6, 2, 4, 3, 5, 1Explanation:  A = 2 is the minima of the left half.B = 5 is the maxima of the right half.
Input: N = 6,  A = 1, B = 3Output: -1Explanation:  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++
Python3
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to generate next permutationvoid 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 functionint factorial(int n){    return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;} // Function to returns all the permutations// of a given array or vectorvector<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 maximasvoid 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 Codeint main(){    int N = 6, A = 2, B = 5;    findPermutation(N, A, B);    return 0;}
# Python code to implement the above approach num =[]# Function to generate next permutationdef 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 functiondef 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 vectordef 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 maximasdef 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 CodeN = 6A = 2B = 5findPermutation(N, A, B) # This code is contributed by Shubham Singh
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.
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++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to get the desired permutationvoid 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 Codeint main(){     int N = 6, A = 2, B = 5;    getpermutation(N, A, B);     return 0;}
// Java program for the above approachimport java.util.*; class GFG{ // Function to get the desired permutationstatic 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 Codepublic 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 permutationdef 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 Codeif __name__ == "__main__":     N = 6    A = 2    B = 5     getpermutation(N, A, B)     # This code is contributed by rakeshsahni
// C# program for the above approachusing 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(N)
 
lokeshpotta20
rakeshsahni
ukasp
samim2000
shubhamsingh84100
adnanirshad158
Algo-Geek 2021
permutation
Algo Geek
Arrays
Combinatorial
Greedy
Arrays
Greedy
permutation
Combinatorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Check if the given string is valid English word or not
Sort strings on the basis of their numeric part
Divide given number into two even parts
Smallest set of vertices to visit all nodes of the given Graph
Count of Palindrome Strings in given Array of strings
Arrays in Java
Arrays in C/C++
Maximum and minimum of an array using minimum number of comparisons
Write a program to reverse an array or string
Program for array rotation