Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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;
            }
        }
    }
}


Output

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>


Output

6 2 4 3 5 1 

Time Complexity: O(N)
Auxiliary Space: O(1) as constant space for variables has been used



Last Updated : 16 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads