Minimum number of prefix reversals to sort permutation of first N numbers

08 Dec, 2021
Given N numbers that have a permutation of first N numbers. In a single operation, any prefix can be reversed. The task is to find the minimum number of such operations such that the numbers in the array are in increasing order. Examples:  
Input : a[] = {3, 1, 2} 
Output : 2 
Step1: Reverse the complete array a, a[] = {2, 1, 3} 
Step2: Reverse the prefix(0-1) in s, a[] = {1, 2, 3} 

Input : a[] = {1, 2, 4, 3} 
Output : 3 
Step1: Reverse the complete array a, a[] = {3, 4, 2, 1} 
Step2: Reverse the prefix(0-1) in s, a[] = {4, 3, 2, 1} 
Step3: Reverse the complete array a, a[] = {1, 2, 3, 4} 
 
The approach to solve this problem is to use BFS.  
Encode the given numbers in a string. Sort the array and encode it into a string destination.
Then do a BFS from the initial permutation. Each time, check all permutations induced by reversing a prefix of current permutation.
If it is not visited, put it into the queue with the count of reversals done.
When the permutation of the encoded string is same as the destination string, return the numbers of reversals required to reach here.
That is, all permutations of strings are done and the minimal of those is returned as the answer.
Below is the implementation of the above approach:  
C++
Java
C#
Javascript
Python3
// C++ program to find// minimum number of prefix reversals// to sort permutation of first N numbers#include <bits/stdc++.h>using namespace std; // Function to return the minimum prefix reversalsint minimumPrefixReversals(int a[], int n){    string start = "";    string destination = "", t, r;    for (int i = 0; i < n; i++) {        // converts the number to a character        // and add  to string        start += to_string(a[i]);    }    sort(a, a + n);    for (int i = 0; i < n; i++) {        destination += to_string(a[i]);    }     // Queue to store the pairs    // of string and number of reversals    queue<pair<string, int> > qu;    pair<string, int> p;     // Initially push the original string    qu.push(make_pair(start, 0));     // if original string is the destination string    if (start == destination) {        return 0;    }     // iterate till queue is empty    while (!qu.empty()) {         // pair at the top        p = qu.front();         // string        t = p.first;         // pop the top-most element        qu.pop();         // perform prefix reversals for all index and push        // in the queue and check for the minimal        for (int j = 2; j <= n; j++) {            r = t;             // reverse the string till prefix j            reverse(r.begin(), r.begin() + j);             // if after reversing the string from first i index            // it is the destination            if (r == destination) {                return p.second + 1;            }             // push the number of reversals for string r            qu.push(make_pair(r, p.second + 1));        }    }} // Driver Codeint main(){     int a[] = { 1, 2, 4, 3 };    int n = sizeof(a) / sizeof(a[0]);     // Calling function    cout << minimumPrefixReversals(a, n);     return 0;}
// Java program to find minimum// number of prefix reversals to// sort permutation of first N numbersimport java.util.*; public class Main{         // function to find minimum prefix reversal through BFS    public static int minimumPrefixReversals(int[] a)    {        // size of array        int n = a.length;                 // string for initial and goal nodes        String start = "", destination = "";                 // string for manipulation in while loop        String original = "",modified = "";                 // node to store temporary values from front of queue        Node temp = null;                 // create the starting string        for (int i = 0; i < n; i++)        start += a[i];                 // sort the array and prepare final destination string        Arrays.sort(a);        for (int i = 0; i < n; i++)            destination += a[i];                 // this queue will store all the BFS siblings        Queue<Node> q = new LinkedList<>();                 // place the starting node in queue        q.add(new Node(start, 0));                 //base case:- if array is already sorted        if (start == destination)            return 0;                          // loop until the size of queue is empty        while (q.size() != 0)        {            // put front node of queue in temporary variable            temp = q.poll();                         // store the original string at this step            original = temp.string;                         for (int j = 2; j <= n; j++)            {                // modified will be used to generate all                // manipulation of original string                // like if original = 1342                // modified = 3142 , 4312 , 2431                                 modified = original;                                 // generate the permutation by reversing                modified = reverse (modified , j);                                 if (modified.equals(destination))                {                    // if string match then return                    // the height of the current node                    return temp.steps + 1;                }                                 // else put this node into queue                q.add(new Node(modified,temp.steps + 1));            }                     }             // if no case match then default value    return Integer.MIN_VALUE;    }         // function to reverse the string upto an index    public static String reverse (String s , int index)    {        char temp []= s.toCharArray();        int i = 0;        while (i < index)        {            char c = temp[i];            temp[i] = temp[index-1];            temp[index-1] = c;            i++;index--;        }        return String.valueOf(temp);    }     // Driver code    public static void main(String []args)    {        int a[] = new int []{1,2,4,3};        System.out.println(minimumPrefixReversals(a));    }         // Node class to store a combined set of values    static class Node    {        public String string ;        public int steps;                 public Node(String string,int steps)        {            this.string = string;            this.steps= steps;        }    }} // This code is contributed by Sparsh Singhal
// C# program to find minimum// number of prefix reversals to// sort permutation of first N numbersusing System;using System.Collections.Generic;             class GFG{    // Node class to store a combined set of values    public class Node    {        public String str;        public int steps;                 public Node(String str,int steps)        {            this.str = str;            this.steps= steps;        }    }         // function to find minimum prefix reversal through BFS    public static int minimumPrefixReversals(int[] a)    {        // size of array        int n = a.Length;                 // string for initial and goal nodes        String start = "", destination = "";                 // string for manipulation in while loop        String original = "", modified = "";                 // node to store temporary values        // from front of queue        Node temp = null;                 // create the starting string        for (int i = 0; i < n; i++)        start += a[i];                 // sort the array and prepare        // final destination string        Array.Sort(a);        for (int i = 0; i < n; i++)            destination += a[i];                 // this queue will store all the BFS siblings        Queue<Node> q = new Queue<Node>();                 // place the starting node in queue        q.Enqueue(new Node(start, 0));                 //base case:- if array is already sorted        if (start == destination)            return 0;                          // loop until the size of queue is empty        while (q.Count != 0)        {            // put front node of queue in temporary variable            temp = q.Dequeue();                         // store the original string at this step            original = temp.str;                         for (int j = 2; j <= n; j++)            {                // modified will be used to generate all                // manipulation of original string                // like if original = 1342                // modified = 3142 , 4312 , 2431                                 modified = original;                                 // generate the permutation by reversing                modified = reverse (modified , j);                                 if (modified.Equals(destination))                {                    // if string match then return                    // the height of the current node                    return temp.steps + 1;                }                                 // else put this node into queue                q.Enqueue(new Node(modified, temp.steps + 1));            }        }                 // if no case match then default value        return int.MinValue;    }         // function to reverse the string upto an index    public static String reverse (String s, int index)    {        char []temp = s.ToCharArray();        int i = 0;        while (i < index)        {            char c = temp[i];            temp[i] = temp[index - 1];            temp[index - 1] = c;            i++;index--;        }        return String.Join("", temp);    }     // Driver code    public static void Main(String []args)    {        int []a = new int []{1, 2, 4, 3};        Console.WriteLine(minimumPrefixReversals(a));    }} // This code is contributed by 29AjayKumar
<script> class Node{    constructor(string,steps)    {        this.string = string;        this.steps= steps;    }} function minimumPrefixReversals(a){    // size of array        let n = a.length;                  // string for initial and goal nodes        let start = "", destination = "";                  // string for manipulation in while loop        let original = "",modified = "";                  // node to store temporary values from front of queue        let temp = null;                  // create the starting string        for (let i = 0; i < n; i++)            start += a[i];                  // sort the array and prepare final destination string        a.sort(function(a,b){return a-b;});        for (let i = 0; i < n; i++)            destination += a[i];                  // this queue will store all the BFS siblings        let q = [];                  // place the starting node in queue        q.push(new Node(start, 0));                  //base case:- if array is already sorted        if (start == destination)            return 0;                            // loop until the size of queue is empty        while (q.length != 0)        {            // put front node of queue in temporary variable            temp = q.shift();                          // store the original string at this step            original = temp.string;                          for (let j = 2; j <= n; j++)            {                // modified will be used to generate all                // manipulation of original string                // like if original = 1342                // modified = 3142 , 4312 , 2431                                  modified = original;                                  // generate the permutation by reversing                modified = reverse (modified , j);                                  if (modified == (destination))                {                    // if string match then return                    // the height of the current node                    return temp.steps + 1;                }                                  // else put this node into queue                q.push(new Node(modified,temp.steps + 1));            }                      }              // if no case match then default value    return Number.MIN_VALUE;} function reverse (s,index){    let temp = s.split("");        let i = 0;        while (i < index)        {            let c = temp[i];            temp[i] = temp[index-1];            temp[index-1] = c;            i++;index--;        }        return (temp).join("");} let a = [1, 2, 4, 3];document.write(minimumPrefixReversals(a)); // This code is contributed by rag2127</script>
# Python3 program to find# minimum number of prefix reversals# to sort permutation of [0] N numbersfrom queue import Queue # Function to return the minimum prefix reversalsdef minimumPrefixReversals( a,  n):    start = ""    destination = ""    for i in range(n):        # converts the number to a character        # and add  to        start += str(a[i])         a.sort()    for i in range(n):        destination += str(a[i])          # Queue to store the pairs    # of  and number of reversals    qu=Queue()     # Initially push the original    qu.put((start, 0))     # if original  is the destination    if (start == destination) :        return 0     # iterate till queue is empty    while qu.not_empty :        # pair at the top        p = qu.get()         #        t = p[0]           # perform prefix reversals for all index and push        # in the queue and check for the minimal        for j in range(2,n+1) :            r = t             # reverse the  till prefix j            tmpR=list(r)            tmpR[:j]=tmpR[j-1::-1]            r=''.join(tmpR)             # if after reversing the  from [0] i index            # it is the destination            if (r == destination) :                return p[1] + 1                          # push the number of reversals for  r            qu.put((r, p[1] + 1))                # Driver Codeif __name__ == '__main__':      a = [ 1, 2, 4, 3]    n = len(a)     # Calling function    print(minimumPrefixReversals(a, n))
3
 
Time Complexity: O(N! * N2) Auxiliary Space: O(N!) 
vaibhav2992
sparsh singhal
29AjayKumar
clintra
akshaysingh98088
surinderdawra388
rag2127
pankajsharmagfg
amartyaghoshgfg
BFS
cpp-pair
cpp-queue
Permutation and Combination
Sorting Quiz
Algorithms
BFS
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
What is Hashing | A Complete Tutorial
Find if there is a path between two vertices in an undirected graph
How to Start Learning DSA?
Complete Roadmap To Learn DSA From Scratch
Types of Complexity Classes | P, NP, CoNP, NP hard and NP complete
Difference between NP hard and NP complete problem
What Should I Learn First: Data Structures or Algorithms?
Ternary Search
K means Clustering - Introduction
Hash Functions and list/types of Hash functions