Skip to content
Related Articles

Related Articles

Improve Article
Count minimum number of moves to front or end to sort an array
  • Difficulty Level : Easy
  • Last Updated : 05 Apr, 2021

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:
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:
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: 
    1. recursive_function(arr, brr, i + 1, j)
    2. recursive_function(arr, brr, i, j + 1)

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that counts the minimum
// moves required to covert 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 array
void 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 code
int 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




// Java program for the above approach
import java.util.*;
import java.io.*;
import java.lang.Math;
 
class GFG{
 
// Function that counts the minimum
// moves required to covert 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 array
static 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 code
public static void main(final String[] args)
{
    int arr[] = { 4, 7, 2, 3, 9 };
     
    minOperationsUtil(arr);
}
}
 
// This code is contributed by bikram2001jha

Python3




# Python3 program for the above approach
 
# Function that counts the minimum
# moves required to covert 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 array
def 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#




// C# program for the above approach
using System;
 
class GFG{
     
// Function that counts the minimum
// moves required to covert 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 array
static 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 code
static void Main()
{
    int[] arr = { 4, 7, 2, 3, 9 };
      
    minOperationsUtil(arr);
}
}
 
// This code is contributed by divyeshrabadiya07

Javascript




<script>
 
// Javascript program for the above approach
 
// Function that counts the minimum
// moves required to covert 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 array
function 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 code
let arr = [ 4, 7, 2, 3, 9 ];
let n = arr.length;
 
minOperationsUtil(arr, n);
     
// This code is contributed by Mayank Tyagi
     
</script>
Output: 
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++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that counts the minimum
// moves required to covert arr[] to brr[]
int minOperations(int arr1[], int arr2[], int i, int j,
                  int n, map<pair<int, int>, int> table)
{
     
    // Base Cases
    pair<int, int> key = {i, j};
     
    if (arr1 == arr2)
        return 0;
    if (i >= n || j >= n)
        return 0;
 
    // If the result is already stored
    if (table.find(key) != table.end())
        return table[key];
 
    // Compute the result
    if (arr1[i] < arr2[j])
        return 1 + minOperations(
            arr1, arr2, i + 1, j + 1, n, table);
 
    // Store the result
    table[key] = max(
        minOperations(arr1, arr2, i, j + 1, n, table),
        minOperations(arr1, arr2, i + 1, j, n, table));
 
    // Return the result
    return table[key];
}
 
// Function that counts the minimum
// moves required to sort the array
void minOperationsUtil(int arr[], int n)
{
    int brr[n];
 
    for(int i = 0; i < n; i++)
        brr[i] = arr[i];
 
    sort(brr, brr + n);
 
    if (brr == arr)
        cout << 0;
 
    else
    {
        map<pair<int, int>, int> table;
         
        cout << n - minOperations(
            brr, arr, 0, 0, n, table);
    }
}
 
// Driver code
int main()
{
    int arr[] = { 4, 7, 2, 3, 9 };
    int n = sizeof(arr) / sizeof(arr[0]);
     
    minOperationsUtil(arr, n);
}
 
// This code is contributed by grand_master

Python3




# Python3 program for the above approach
 
# Function to find the minimum number
# of moves required to sort the array
def minOperations(arr1, arr2, i, j, table):
     
    key = (i, j)
 
    # Base Cases
    if arr1 == arr2:
        return 0
    if i >= len(arr1) or j >= len(arr2):
        return 0
 
    # If the result is already stored
    if key in table:
        return table[key]
 
    # Compute the result
    if arr1[i] < arr2[j]:
        return 1 + minOperations(
                   arr1, arr2, i + 1,
                   j + 1, table)
 
    # Store the result
    table[key] = max(
        minOperations(arr1, arr2, i,
        j + 1, table),
         
        minOperations(arr1, arr2, i + 1,
        j, table))
 
    # Return the result
    return table[key]
 
# Function to print the minimum
# moves required to sort the array
def minOperationsUtil(arr):
 
    brr = sorted(arr)
    table = dict()
     
    # If both the arrays are equal
    if brr == arr:
         
        # No moves required
        print(0)
 
    # Otherwise
    else:
        print(len(brr) -
              minOperations(brr, arr, 0, 0, table))
 
# Driver Code
 
arr = [4, 7, 2, 3, 9]
 
minOperationsUtil(arr)

C#




// C# program for the above approach
using System;
using System.Collections.Generic; 
class GFG
{
     
    // Function that counts the minimum
    // moves required to covert arr[] to brr[]
    static int minOperations(int[] arr1, int[] arr2, int i, int j,
                      int n, Dictionary<Tuple<int, int>, int> table)
    {
          
        // Base Cases
        Tuple<int, int> key = new Tuple<int, int>(i, j);       
        if (arr1 == arr2)
            return 0;
        if (i >= n || j >= n)
            return 0;
      
        // If the result is already stored
        if (table.ContainsKey(key))
            return table[key];
      
        // Compute the result
        if (arr1[i] < arr2[j])
            return 1 + minOperations(
                arr1, arr2, i + 1, j + 1, n, table);
      
        // Store the result
        table[key] = Math.Max(
            minOperations(arr1, arr2, i, j + 1, n, table),
            minOperations(arr1, arr2, i + 1, j, n, table));
      
        // Return the result
        return table[key];
    }
      
    // Function that counts the minimum
    // moves required to sort the array
    static void minOperationsUtil(int[] arr, int n)
    {
        int[] brr = new int[n];    
        for(int i = 0; i < n; i++)
            brr[i] = arr[i];    
        Array.Sort(brr);   
        if (brr == arr)
            Console.Write(0);    
        else
        {
            Dictionary<Tuple<int, int>, int> table =
              new Dictionary<Tuple<int, int>, int>();           
            Console.Write(n - minOperations(brr, arr, 0, 0, n, table));
        }
    }
   
  // Driver code
  static void Main()
  {
    int[] arr = { 4, 7, 2, 3, 9 };
    int n = arr.Length;
      
    minOperationsUtil(arr, n);
  }
}
 
// This code is contributed by divyesh072019

Output:

2

Time Complexity: O(N)

Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live 




My Personal Notes arrow_drop_up
Recommended Articles
Page :