Count minimum number of moves to front or end to sort an array - GeeksforGeeks

25 Apr, 2022
Given an array arr[] of size N, the task is to find the minimum moves to the beginning or end of the array required to make the array sorted in non-decreasing order.
Examples: 
Input: arr[] = {4, 7, 2, 3, 9} Output: 2 Explanation: Perform the following operations: Step 1: Move the element 3 to the start of the array. Now, arr[] modifies to {3, 4, 7, 2, 9}. Step 2: Move the element 2 to the start of the array. Now, arr[] modifies to {2, 3, 4, 7, 9}. Now, the resultant array is sorted. Therefore, the minimum moves required is 2. 
Input: arr[] = {1, 4, 5, 7, 12} Output: 0 Explanation: The array is already sorted. Therefore, no moves required. 
Naive Approach: The simplest approach is to check for every array element, how many moves are required to sort the given array arr[]. For each array element, if it is not at its sorted position, the following possibilities arise: 
Either move the current element to the front.
Otherwise, move the current element to the end.
After performing the above operations, print the minimum number of operations required to make the array sorted. Below is the recurrence relation of the same: 
If the array arr[] is equal to the array brr[], then return 0.
If arr[i] < brr[j], then count of operation will be:
1 + recursive_function(arr, brr, i + 1, j + 1) 
Otherwise, the count of operation can be calculated by taking the maximum of the following states: recursive_function(arr, brr, i + 1, j)recursive_function(arr, brr, i, j + 1)
recursive_function(arr, brr, i + 1, j)recursive_function(arr, brr, i, j + 1)
recursive_function(arr, brr, i + 1, j)
recursive_function(arr, brr, i, j + 1)
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 that counts the minimum// moves required to convert arr[] to brr[]int minOperations(int arr1[], int arr2[],                  int i, int j,                  int n){  // Base Case  int f = 0;  for (int i = 0; i < n; i++)  {    if (arr1[i] != arr2[i])      f = 1;    break;  }  if (f == 0)    return 0;   if (i >= n || j >= n)    return 0;   // If arr[i] < arr[j]  if (arr1[i] < arr2[j])     // Include the current element    return 1 + minOperations(arr1, arr2,                             i + 1, j + 1, n);   // Otherwise, excluding the current element  return max(minOperations(arr1, arr2,                           i, j + 1, n),             minOperations(arr1, arr2,                           i + 1, j, n));} // Function that counts the minimum// moves required to sort the arrayvoid minOperationsUtil(int arr[], int n){  int brr[n];   for (int i = 0; i < n; i++)    brr[i] = arr[i];   sort(brr, brr + n);  int f = 0;   // If both the arrays are equal  for (int i = 0; i < n; i++)  {    if (arr[i] != brr[i])       // No moves required      f = 1;    break;  }     // Otherwise  if (f == 1)         // Print minimum    // operations required    cout << (minOperations(arr, brr,                           0, 0, n));  else    cout << "0";} // Driver codeint main(){    int arr[] = {4, 7, 2, 3, 9};    int n = sizeof(arr) / sizeof(arr[0]);    minOperationsUtil(arr, n);} // This code is contributed by Chitranayal
// Java program for the above approachimport java.util.*;import java.io.*;import java.lang.Math; class GFG{ // Function that counts the minimum// moves required to convert arr[] to brr[]static int minOperations(int arr1[], int arr2[],                         int i, int j){         // Base Case    if (arr1.equals(arr2))        return 0;               if (i >= arr1.length || j >= arr2.length)        return 0;           // If arr[i] < arr[j]    if (arr1[i] < arr2[j])             // Include the current element        return 1 + minOperations(arr1, arr2,                                 i + 1, j + 1);              // Otherwise, excluding the current element    return Math.max(minOperations(arr1, arr2,                                  i, j + 1),                    minOperations(arr1, arr2,                                  i + 1, j));} // Function that counts the minimum// moves required to sort the arraystatic void minOperationsUtil(int[] arr){    int brr[] = new int[arr.length];         for(int i = 0; i < arr.length; i++)        brr[i] = arr[i];             Arrays.sort(brr);           // If both the arrays are equal    if (arr.equals(brr))             // No moves required        System.out.print("0");             // Otherwise    else             // Print minimum operations required        System.out.println(minOperations(arr, brr,                                         0, 0));} // Driver codepublic static void main(final String[] args){    int arr[] = { 4, 7, 2, 3, 9 };         minOperationsUtil(arr);}} // This code is contributed by bikram2001jha
# Python3 program for the above approach # Function that counts the minimum# moves required to convert arr[] to brr[]def minOperations(arr1, arr2, i, j):         # Base Case    if arr1 == arr2:        return 0             if i >= len(arr1) or j >= len(arr2):        return 0         # If arr[i] < arr[j]    if arr1[i] < arr2[j]:                 # Include the current element        return 1 \        + minOperations(arr1, arr2, i + 1, j + 1)             # Otherwise, excluding the current element    return max(minOperations(arr1, arr2, i, j + 1),               minOperations(arr1, arr2, i + 1, j))     # Function that counts the minimum# moves required to sort the arraydef minOperationsUtil(arr):         brr = sorted(arr);         # If both the arrays are equal    if(arr == brr):                 # No moves required        print("0")     # Otherwise    else:                 # Print minimum operations required        print(minOperations(arr, brr, 0, 0)) # Driver Code arr = [4, 7, 2, 3, 9] minOperationsUtil(arr)
// C# program for the above approachusing System; class GFG{     // Function that counts the minimum// moves required to convert arr[] to brr[]static int minOperations(int[] arr1, int[] arr2,                         int i, int j){         // Base Case    if (arr1.Equals(arr2))        return 0;                if (i >= arr1.Length ||        j >= arr2.Length)        return 0;            // If arr[i] < arr[j]    if (arr1[i] < arr2[j])              // Include the current element        return 1 + minOperations(arr1, arr2,                                 i + 1, j + 1);               // Otherwise, excluding the current element    return Math.Max(minOperations(arr1, arr2,                                  i, j + 1),                    minOperations(arr1, arr2,                                  i + 1, j));} // Function that counts the minimum// moves required to sort the arraystatic void minOperationsUtil(int[] arr){    int[] brr = new int[arr.Length];          for(int i = 0; i < arr.Length; i++)        brr[i] = arr[i];              Array.Sort(brr);            // If both the arrays are equal    if (arr.Equals(brr))              // No moves required        Console.Write("0");              // Otherwise    else              // Print minimum operations required        Console.WriteLine(minOperations(arr, brr,                                         0, 0));} // Driver codestatic void Main(){    int[] arr = { 4, 7, 2, 3, 9 };          minOperationsUtil(arr);}} // This code is contributed by divyeshrabadiya07
<script> // Javascript program for the above approach // Function that counts the minimum// moves required to convert arr[] to brr[]function minOperations(arr1, arr2,                       i, j, n){         // Base Case    let f = 0;    for(let i = 0; i < n; i++)    {        if (arr1[i] != arr2[i])        f = 1;        break;    }    if (f == 0)        return 0;         if (i >= n || j >= n)        return 0;         // If arr[i] < arr[j]    if (arr1[i] < arr2[j])             // Include the current element        return 1 + minOperations(arr1, arr2,                                 i + 1, j + 1, n);         // Otherwise, excluding the current element    return Math.max(minOperations(arr1, arr2,                                  i, j + 1, n),                    minOperations(arr1, arr2,                                  i + 1, j, n));} // Function that counts the minimum// moves required to sort the arrayfunction minOperationsUtil(arr, n){    let brr = new Array(n);         for(let i = 0; i < n; i++)        brr[i] = arr[i];         brr.sort();    let f = 0;         // If both the arrays are equal    for(let i = 0; i < n; i++)    {        if (arr[i] != brr[i])             // No moves required        f = 1;        break;    }         // Otherwise    if (f == 1)                 // Print minimum        // operations required        document.write(minOperations(arr, brr,                                     0, 0, n));    else        cout << "0";} // Driver codelet arr = [ 4, 7, 2, 3, 9 ];let n = arr.length; minOperationsUtil(arr, n);     // This code is contributed by Mayank Tyagi     </script>
2
Time Complexity: O(2N) Auxiliary Space: O(N) 
Efficient Approach: The above approach has many overlapping subproblems. Therefore, the above approach can be optimized using Dynamic programming. Follow the steps below to solve the problem: 
Maintain a 2D array table[][] to store the computed results.
Apply recursion to solve the problem using the results of smaller subproblems.
If arr1[i] < arr2[j], then return 1 + minOperations(arr1, arr2, i + 1, j – 1, table)
Otherwise, either move the i-th element of the array to the end or the j-th element of the array to the front. Therefore, the recurrence relation is:
table[i][j] = max(minOperations(arr1, arr2, i, j + 1, table), minOperations(arr1, arr2, i + 1, j, table))
Finally, print the value stored in table[0][N – 1].
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 that counts the minimum// moves required to convert arr[] to brr[]int minOperations(int arr1[], int arr2[],                  int i, int j,                  int n){  // Base Case  int f = 0;  for (int i = 0; i < n; i++)  {    if (arr1[i] != arr2[i])      f = 1;    break;  }  if (f == 0)    return 0;   if (i >= n || j >= n)    return 0;   // If arr[i] < arr[j]  if (arr1[i] < arr2[j])     // Include the current element    return 1 + minOperations(arr1, arr2,                             i + 1, j + 1, n);   // Otherwise, excluding the current element  return max(minOperations(arr1, arr2,                           i, j + 1, n),             minOperations(arr1, arr2,                           i + 1, j, n));} // Function that counts the minimum// moves required to sort the arrayvoid minOperationsUtil(int arr[], int n){  int brr[n];   for (int i = 0; i < n; i++)    brr[i] = arr[i];   sort(brr, brr + n);  int f = 0;   // If both the arrays are equal  for (int i = 0; i < n; i++)  {    if (arr[i] != brr[i])       // No moves required      f = 1;    break;  }     // Otherwise  if (f == 1)         // Print minimum    // operations required    cout << (minOperations(arr, brr,                           0, 0, n));  else    cout << "0";} // Driver codeint main(){    int arr[] = {4, 7, 2, 3, 9};    int n = sizeof(arr) / sizeof(arr[0]);    minOperationsUtil(arr, n);} // This code is contributed by Chitranayal
// Java program for the above approachimport java.util.*;import java.io.*;import java.lang.Math; class GFG{ // Function that counts the minimum// moves required to convert arr[] to brr[]static int minOperations(int arr1[], int arr2[],                         int i, int j){         // Base Case    if (arr1.equals(arr2))        return 0;               if (i >= arr1.length || j >= arr2.length)        return 0;           // If arr[i] < arr[j]    if (arr1[i] < arr2[j])             // Include the current element        return 1 + minOperations(arr1, arr2,                                 i + 1, j + 1);              // Otherwise, excluding the current element    return Math.max(minOperations(arr1, arr2,                                  i, j + 1),                    minOperations(arr1, arr2,                                  i + 1, j));} // Function that counts the minimum// moves required to sort the arraystatic void minOperationsUtil(int[] arr){    int brr[] = new int[arr.length];         for(int i = 0; i < arr.length; i++)        brr[i] = arr[i];             Arrays.sort(brr);           // If both the arrays are equal    if (arr.equals(brr))             // No moves required        System.out.print("0");             // Otherwise    else             // Print minimum operations required        System.out.println(minOperations(arr, brr,                                         0, 0));} // Driver codepublic static void main(final String[] args){    int arr[] = { 4, 7, 2, 3, 9 };         minOperationsUtil(arr);}} // This code is contributed by bikram2001jha
# Python3 program for the above approach # Function that counts the minimum# moves required to convert arr[] to brr[]def minOperations(arr1, arr2, i, j):         # Base Case    if arr1 == arr2:        return 0             if i >= len(arr1) or j >= len(arr2):        return 0         # If arr[i] < arr[j]    if arr1[i] < arr2[j]:                 # Include the current element        return 1 \        + minOperations(arr1, arr2, i + 1, j + 1)             # Otherwise, excluding the current element    return max(minOperations(arr1, arr2, i, j + 1),               minOperations(arr1, arr2, i + 1, j))     # Function that counts the minimum# moves required to sort the arraydef minOperationsUtil(arr):         brr = sorted(arr);         # If both the arrays are equal    if(arr == brr):                 # No moves required        print("0")     # Otherwise    else:                 # Print minimum operations required        print(minOperations(arr, brr, 0, 0)) # Driver Code arr = [4, 7, 2, 3, 9] minOperationsUtil(arr)
// C# program for the above approachusing System; class GFG{     // Function that counts the minimum// moves required to convert arr[] to brr[]static int minOperations(int[] arr1, int[] arr2,                         int i, int j){         // Base Case    if (arr1.Equals(arr2))        return 0;                if (i >= arr1.Length ||        j >= arr2.Length)        return 0;            // If arr[i] < arr[j]    if (arr1[i] < arr2[j])              // Include the current element        return 1 + minOperations(arr1, arr2,                                 i + 1, j + 1);               // Otherwise, excluding the current element    return Math.Max(minOperations(arr1, arr2,                                  i, j + 1),                    minOperations(arr1, arr2,                                  i + 1, j));} // Function that counts the minimum// moves required to sort the arraystatic void minOperationsUtil(int[] arr){    int[] brr = new int[arr.Length];          for(int i = 0; i < arr.Length; i++)        brr[i] = arr[i];              Array.Sort(brr);            // If both the arrays are equal    if (arr.Equals(brr))              // No moves required        Console.Write("0");              // Otherwise    else              // Print minimum operations required        Console.WriteLine(minOperations(arr, brr,                                         0, 0));} // Driver codestatic void Main(){    int[] arr = { 4, 7, 2, 3, 9 };          minOperationsUtil(arr);}} // This code is contributed by divyeshrabadiya07
<script> // Javascript program for the above approach // Function that counts the minimum// moves required to convert arr[] to brr[]function minOperations(arr1, arr2,                       i, j, n){         // Base Case    let f = 0;    for(let i = 0; i < n; i++)    {        if (arr1[i] != arr2[i])        f = 1;        break;    }    if (f == 0)        return 0;         if (i >= n || j >= n)        return 0;         // If arr[i] < arr[j]    if (arr1[i] < arr2[j])             // Include the current element        return 1 + minOperations(arr1, arr2,                                 i + 1, j + 1, n);         // Otherwise, excluding the current element    return Math.max(minOperations(arr1, arr2,                                  i, j + 1, n),                    minOperations(arr1, arr2,                                  i + 1, j, n));} // Function that counts the minimum// moves required to sort the arrayfunction minOperationsUtil(arr, n){    let brr = new Array(n);         for(let i = 0; i < n; i++)        brr[i] = arr[i];         brr.sort();    let f = 0;         // If both the arrays are equal    for(let i = 0; i < n; i++)    {        if (arr[i] != brr[i])             // No moves required        f = 1;        break;    }         // Otherwise    if (f == 1)                 // Print minimum        // operations required        document.write(minOperations(arr, brr,                                     0, 0, n));    else        cout << "0";} // Driver codelet arr = [ 4, 7, 2, 3, 9 ];let n = arr.length; minOperationsUtil(arr, n);     // This code is contributed by Mayank Tyagi     </script>
2
Time Complexity: O(N2)
Auxiliary Space: O(N2)
We are using two variables namely i and j to determine a unique state of the DP(Dynamic Programming) stage, and each one of i and j can attain N values from 0 to N-1. Thus the recursion will have N*N number of transitions each of O(1) cost. Hence the time complexity is O(N*N).
More Efficient Approach: Sort the given array keeping index of elements aside, now find the longest streak of increasing values of index. This longest streak reflects that these elements are already sorted and do the above operation on rest of the elements. Let’s take above array as an example, arr = [8, 2, 1, 5, 4] after sorting their index values will be – [2, 1, 4, 3, 0], here longest streak is 2(1, 4) which means except these 2 numbers we have to follow the above operation and sort the array therefore, 5(arr.length) – 2 = 3 will be the answer.
Implementation of above approach:
C++
Java
Python3
Javascript
// C++ algorithm of above approach #include <bits/stdc++.h>#include <vector>using namespace std; // Function to find minimum number of operation required// so that array becomes meaningfulint minOperations(int arr[], int n){    // Initializing vector of pair type which contains value    // and index of arr    vector<pair<int, int>> vect;    for (int i = 0; i < n; i++) {        vect.push_back(make_pair(arr[i], i));    }     // Sorting array num on the basis of value    sort(vect.begin(), vect.end());     // Initializing variables used to find maximum    // length of increasing streak in index    int res = 1;    int streak = 1;    int prev = vect[0].second;    for (int i = 1; i < n; i++) {        if (prev < vect[i].second) {            res++;             // Updating streak            streak = max(streak, res);        }        else            res = 1;        prev = vect[i].second;    }     // Returning number of elements left except streak    return n - streak;} // Driver Codeint main(){    int arr[] = { 4, 7, 2, 3, 9 };    int n = sizeof(arr) / sizeof(arr[0]);    int count = minOperations(arr, n);    cout << count;}
// Java algorithm for above approach import java.util.*; class GFG {     // Pair class which will store element of array with its    // index    public static class Pair {        int val;        int idx;        Pair(int val, int idx)        {            this.val = val;            this.idx = idx;        }    }     // Driver code    public static void main(String[] args)    {        int n = 5;        int[] arr = { 4, 7, 2, 3, 9 };        System.out.println(minOperations(arr, n));    }     // Function to find minimum number of operation required    // so that array becomes meaningful    public static int minOperations(int[] arr, int n)    {        // Initializing array of Pair type which can be used        // to sort arr with respect to its values        Pair[] num = new Pair[n];        for (int i = 0; i < n; i++) {            num[i] = new Pair(arr[i], i);        }         // Sorting array num on the basis of value        Arrays.sort(num, (Pair a, Pair b) -> a.val - b.val);         // Initializing variables used to find maximum        // length of increasing streak in index        int res = 1;        int streak = 1;        int prev = num[0].idx;        for (int i = 1; i < n; i++) {            if (prev < num[i].idx) {                res++;                 // Updating streak                streak = Math.max(res, streak);            }            else                res = 1;            prev = num[i].idx;        }         // Returning number of elements left except streak        return n - streak;    }}
# Python algorithm of above approach # Function to find minimum number of operation required# so that array becomes meaningfuldef minOperations(arr, n):     # Initializing vector of pair type which contains value    # and index of arr    vect = []    for i in range(n):        vect.append([arr[i], i])     # Sorting array num on the basis of value    vect.sort()     # Initializing variables used to find maximum    # length of increasing streak in index    res = 1    streak = 1    prev = vect[0][1]    for i in range(1,n):        if (prev < vect[i][1]):            res += 1             # Updating streak            streak = max(streak, res)        else:            res = 1        prev = vect[i][1]     # Returning number of elements left except streak    return n - streak # Driver codearr = [ 4, 7, 2, 3, 9 ]n = len(arr)count = minOperations(arr, n)print(count) # This code is contributed by shinjanpatra.
<script> // JavaScript algorithm of above approach  // Function to find minimum number of operation required// so that array becomes meaningfulfunction minOperations(arr, n){    // Initializing vector of pair type which contains value    // and index of arr    let vect = [];    for (let i = 0; i < n; i++) {        vect.push([arr[i], i]);    }     // Sorting array num on the basis of value    vect.sort();     // Initializing variables used to find maximum    // length of increasing streak in index    let res = 1;    let streak = 1;    let prev = vect[0][1];    for (let i = 1; i < n; i++) {        if (prev < vect[i][1]) {            res++;             // Updating streak            streak = Math.max(streak, res);        }        else            res = 1;        prev = vect[i][1];    }     // Returning number of elements left except streak    return n - streak;} // driver ocdelet arr = [ 4, 7, 2, 3, 9 ];let n = arr.length;let count = minOperations(arr, n);document.write(count,"</br>"); // This code is contributed by shinjanpatra.</script>
2
Time complexity: O(nlogn)
Auxiliary Space: O(n)
bikram2001jha
ukasp
divyeshrabadiya07
grand_master
divyesh072019
mayanktyagi1709
mukesh07
anilyogi2801
suresh07
Kdheeraj
sagar0719kumar
surindertarika1234
shinjanpatra
sumitgumber28
array-rearrange
Arrays
Dynamic Programming
Mathematical
Recursion
Sorting
Arrays
Dynamic Programming
Mathematical
Recursion
Sorting
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Stack Data Structure (Introduction and Program)
Introduction to Arrays
Multidimensional Arrays in Java
0-1 Knapsack Problem | DP-10
Program for Fibonacci numbers
Longest Common Subsequence | DP-4
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16