Count minimum number of moves to front or end to sort an array
Last Updated :
19 Jun, 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)
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minOperations( int arr1[], int arr2[],
int i, int j,
int n)
{
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 (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1, j + 1, n);
return max(minOperations(arr1, arr2,
i, j + 1, n),
minOperations(arr1, arr2,
i + 1, j, n));
}
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;
for ( int i = 0; i < n; i++)
{
if (arr[i] != brr[i])
f = 1;
break ;
}
if (f == 1)
cout << (minOperations(arr, brr,
0, 0, n));
else
cout << "0" ;
}
int main()
{
int arr[] = {4, 7, 2, 3, 9};
int n = sizeof (arr) / sizeof (arr[0]);
minOperationsUtil(arr, n);
}
|
Java
import java.util.*;
import java.io.*;
import java.lang.Math;
class GFG{
static int minOperations( int arr1[], int arr2[],
int i, int j)
{
if (arr1.equals(arr2))
return 0 ;
if (i >= arr1.length || j >= arr2.length)
return 0 ;
if (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1 , j + 1 );
return Math.max(minOperations(arr1, arr2,
i, j + 1 ),
minOperations(arr1, arr2,
i + 1 , j));
}
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 (arr.equals(brr))
System.out.print( "0" );
else
System.out.println(minOperations(arr, brr,
0 , 0 ));
}
public static void main( final String[] args)
{
int arr[] = { 4 , 7 , 2 , 3 , 9 };
minOperationsUtil(arr);
}
}
|
Python3
def minOperations(arr1, arr2, i, j):
if arr1 = = arr2:
return 0
if i > = len (arr1) or j > = len (arr2):
return 0
if arr1[i] < arr2[j]:
return 1 \
+ minOperations(arr1, arr2, i + 1 , j + 1 )
return max (minOperations(arr1, arr2, i, j + 1 ),
minOperations(arr1, arr2, i + 1 , j))
def minOperationsUtil(arr):
brr = sorted (arr);
if (arr = = brr):
print ( "0" )
else :
print (minOperations(arr, brr, 0 , 0 ))
arr = [ 4 , 7 , 2 , 3 , 9 ]
minOperationsUtil(arr)
|
C#
using System;
class GFG{
static int minOperations( int [] arr1, int [] arr2,
int i, int j)
{
if (arr1.Equals(arr2))
return 0;
if (i >= arr1.Length ||
j >= arr2.Length)
return 0;
if (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1, j + 1);
return Math.Max(minOperations(arr1, arr2,
i, j + 1),
minOperations(arr1, arr2,
i + 1, j));
}
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 (arr.Equals(brr))
Console.Write( "0" );
else
Console.WriteLine(minOperations(arr, brr,
0, 0));
}
static void Main()
{
int [] arr = { 4, 7, 2, 3, 9 };
minOperationsUtil(arr);
}
}
|
Javascript
<script>
function minOperations(arr1, arr2,
i, j, n)
{
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 (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1, j + 1, n);
return Math.max(minOperations(arr1, arr2,
i, j + 1, n),
minOperations(arr1, arr2,
i + 1, j, n));
}
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;
for (let i = 0; i < n; i++)
{
if (arr[i] != brr[i])
f = 1;
break ;
}
if (f == 1)
document.write(minOperations(arr, brr,
0, 0, n));
else
cout << "0" ;
}
let arr = [ 4, 7, 2, 3, 9 ];
let n = arr.length;
minOperationsUtil(arr, n);
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int minOperations( int arr1[], int arr2[],
int i, int j,
int n)
{
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 (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1, j + 1, n);
return max(minOperations(arr1, arr2,
i, j + 1, n),
minOperations(arr1, arr2,
i + 1, j, n));
}
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;
for ( int i = 0; i < n; i++)
{
if (arr[i] != brr[i])
f = 1;
break ;
}
if (f == 1)
cout << (minOperations(arr, brr,
0, 0, n));
else
cout << "0" ;
}
int main()
{
int arr[] = {4, 7, 2, 3, 9};
int n = sizeof (arr) / sizeof (arr[0]);
minOperationsUtil(arr, n);
}
|
Java
import java.util.*;
import java.io.*;
import java.lang.Math;
class GFG{
static int minOperations( int arr1[], int arr2[],
int i, int j)
{
if (arr1.equals(arr2))
return 0 ;
if (i >= arr1.length || j >= arr2.length)
return 0 ;
if (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1 , j + 1 );
return Math.max(minOperations(arr1, arr2,
i, j + 1 ),
minOperations(arr1, arr2,
i + 1 , j));
}
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 (arr.equals(brr))
System.out.print( "0" );
else
System.out.println(minOperations(arr, brr,
0 , 0 ));
}
public static void main( final String[] args)
{
int arr[] = { 4 , 7 , 2 , 3 , 9 };
minOperationsUtil(arr);
}
}
|
Python3
def minOperations(arr1, arr2, i, j):
if arr1 = = arr2:
return 0
if i > = len (arr1) or j > = len (arr2):
return 0
if arr1[i] < arr2[j]:
return 1 \
+ minOperations(arr1, arr2, i + 1 , j + 1 )
return max (minOperations(arr1, arr2, i, j + 1 ),
minOperations(arr1, arr2, i + 1 , j))
def minOperationsUtil(arr):
brr = sorted (arr);
if (arr = = brr):
print ( "0" )
else :
print (minOperations(arr, brr, 0 , 0 ))
arr = [ 4 , 7 , 2 , 3 , 9 ]
minOperationsUtil(arr)
|
C#
using System;
class GFG{
static int minOperations( int [] arr1, int [] arr2,
int i, int j)
{
if (arr1.Equals(arr2))
return 0;
if (i >= arr1.Length ||
j >= arr2.Length)
return 0;
if (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1, j + 1);
return Math.Max(minOperations(arr1, arr2,
i, j + 1),
minOperations(arr1, arr2,
i + 1, j));
}
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 (arr.Equals(brr))
Console.Write( "0" );
else
Console.WriteLine(minOperations(arr, brr,
0, 0));
}
static void Main()
{
int [] arr = { 4, 7, 2, 3, 9 };
minOperationsUtil(arr);
}
}
|
Javascript
<script>
function minOperations(arr1, arr2,
i, j, n)
{
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 (arr1[i] < arr2[j])
return 1 + minOperations(arr1, arr2,
i + 1, j + 1, n);
return Math.max(minOperations(arr1, arr2,
i, j + 1, n),
minOperations(arr1, arr2,
i + 1, j, n));
}
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;
for (let i = 0; i < n; i++)
{
if (arr[i] != brr[i])
f = 1;
break ;
}
if (f == 1)
document.write(minOperations(arr, brr,
0, 0, n));
else
cout << "0" ;
}
let arr = [ 4, 7, 2, 3, 9 ];
let n = arr.length;
minOperationsUtil(arr, n);
</script>
|
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++
#include <bits/stdc++.h>
#include <vector>
using namespace std;
int minOperations( int arr[], int n)
{
vector<pair< int , int >> vect;
for ( int i = 0; i < n; i++) {
vect.push_back(make_pair(arr[i], i));
}
sort(vect.begin(), vect.end());
int res = 1;
int streak = 1;
int prev = vect[0].second;
for ( int i = 1; i < n; i++) {
if (prev < vect[i].second) {
res++;
streak = max(streak, res);
}
else
res = 1;
prev = vect[i].second;
}
return n - streak;
}
int main()
{
int arr[] = { 4, 7, 2, 3, 9 };
int n = sizeof (arr) / sizeof (arr[0]);
int count = minOperations(arr, n);
cout << count;
}
|
Java
import java.util.*;
class GFG {
public static class Pair {
int val;
int idx;
Pair( int val, int idx)
{
this .val = val;
this .idx = idx;
}
}
public static void main(String[] args)
{
int n = 5 ;
int [] arr = { 4 , 7 , 2 , 3 , 9 };
System.out.println(minOperations(arr, n));
}
public static int minOperations( int [] arr, int n)
{
Pair[] num = new Pair[n];
for ( int i = 0 ; i < n; i++) {
num[i] = new Pair(arr[i], i);
}
Arrays.sort(num, (Pair a, Pair b) -> a.val - b.val);
int res = 1 ;
int streak = 1 ;
int prev = num[ 0 ].idx;
for ( int i = 1 ; i < n; i++) {
if (prev < num[i].idx) {
res++;
streak = Math.max(res, streak);
}
else
res = 1 ;
prev = num[i].idx;
}
return n - streak;
}
}
|
Python3
def minOperations(arr, n):
vect = []
for i in range (n):
vect.append([arr[i], i])
vect.sort()
res = 1
streak = 1
prev = vect[ 0 ][ 1 ]
for i in range ( 1 ,n):
if (prev < vect[i][ 1 ]):
res + = 1
streak = max (streak, res)
else :
res = 1
prev = vect[i][ 1 ]
return n - streak
arr = [ 4 , 7 , 2 , 3 , 9 ]
n = len (arr)
count = minOperations(arr, n)
print (count)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
class Pair {
public int val;
public int idx;
public Pair( int val, int idx)
{
this .val = val;
this .idx = idx;
}
}
class Comp : IComparer<Pair>{
public int Compare(Pair a, Pair b)
{
return a.val - b.val;
}
}
public static int minOperations( int [] arr, int n)
{
Pair[] num = new Pair[n];
for ( int i = 0 ; i < n ; i++) {
num[i] = new Pair(arr[i], i);
}
Array.Sort(num, new Comp());
int res = 1;
int streak = 1;
int prev = num[0].idx;
for ( int i = 1 ; i < n ; i++) {
if (prev < num[i].idx) {
res++;
streak = Math.Max(res, streak);
}
else {
res = 1;
}
prev = num[i].idx;
}
return n - streak;
}
public static void Main( string [] args){
int n = 5;
int [] arr = new int []{ 4, 7, 2, 3, 9 };
Console.WriteLine(minOperations(arr, n));
}
}
|
Javascript
<script>
function minOperations(arr, n)
{
let vect = [];
for (let i = 0; i < n; i++) {
vect.push([arr[i], i]);
}
vect.sort();
let res = 1;
let streak = 1;
let prev = vect[0][1];
for (let i = 1; i < n; i++) {
if (prev < vect[i][1]) {
res++;
streak = Math.max(streak, res);
}
else
res = 1;
prev = vect[i][1];
}
return n - streak;
}
let arr = [ 4, 7, 2, 3, 9 ];
let n = arr.length;
let count = minOperations(arr, n);
document.write(count, "</br>" );
</script>
|
Time complexity: O(nlogn)
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...