Open In App

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

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
 

Below is the implementation of the above approach: 
 




// 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 reversals
int 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 Code
int 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 numbers
import 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 numbers
using 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 numbers
from queue import Queue
 
# Function to return the minimum prefix reversals
def 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 Code
if __name__ == '__main__':
 
 
    a = [ 1, 2, 4, 3]
    n = len(a)
 
    # Calling function
    print(minimumPrefixReversals(a, n))

Output: 
3

 

Time Complexity: O(N! * N2
Auxiliary Space: O(N!) 


Article Tags :