Problem Statement
Given an array arr[] containing every integer from 1 to n exactly once, we need to sort the array in ascending order.
In one operation, we can:
Pick any element.
Move it to the beginning, or
Move it to the end.
We need to find the minimum number of operations required to sort the array.
Example
Input:
[2, 1, 3]
Output:
1Move 1 to the beginning:
[2, 1, 3]
↓
[1, 2, 3]So the answer is 1.
Key Observation
The most important part of this problem is understanding which elements do not need to be moved.
The final sorted array must be:
[1, 2, 3, 4, 5, ..., n]Suppose some elements are already in the correct relative order:
1, 2, 3If we leave these elements untouched, we can move all the other elements to the beginning or end.
Therefore, instead of directly finding the elements to move, we find:
The maximum number of elements that can remain untouched.
Then:
Minimum moves = n - maximum elements we can keepWhat Sequence Can Be Kept?
The elements we keep must be:
In increasing order.
Consecutive values.
For example:
2, 3, 4, 5is valid.
But:
1, 3, 4is not valid because 2 is missing.
Similarly:
2, 4, 5is not valid.
So we are looking for the longest sequence:
x, x+1, x+2, x+3, ...where these values already appear in the correct order in the array.
Example
Consider:
arr = [4, 3, 1, 2]The positions of each value are:
Value Position
1 2
2 3
3 1
4 0Now check consecutive values.
For 1 and 2:
position[1] < position[2]
2 < 3This is true.
So:
1, 2can remain untouched.
Now check 2 and 3:
position[2] < position[3]
3 < 1This is false.
So the longest sequence is:
1, 2Length = 2.
There are 4 elements total.
Therefore:
Minimum moves = 4 - 2
= 2Why Do We Need a Position Array?
We need to quickly determine where each value occurs.
Create:
int[] pos = new int[n + 1];For every element:
pos[arr[i]] = i;For:
arr = [4, 3, 1, 2]we get:
pos[1] = 2
pos[2] = 3
pos[3] = 1
pos[4] = 0Now checking whether x comes before x + 1 is very easy:
pos[x] < pos[x + 1]This takes O(1) time.
Java Code
class Solution {
public int minMoves(int[] arr) {
int n = arr.length;
// Store the position of every value
int[] pos = new int[n + 1];
for (int i = 0; i < n; i++) {
pos[arr[i]] = i;
}
int maxLen = 1;
int currentLen = 1;
// Find the longest consecutive sequence
// that already appears in the correct order
for (int value = 1; value < n; value++) {
if (pos[value] < pos[value + 1]) {
currentLen++;
} else {
currentLen = 1;
}
maxLen = Math.max(maxLen, currentLen);
}
// All other elements need to be moved
return n - maxLen;
}
}
Join the conversation! Your thoughts help the community grow.