问题
Given an array of distinct integers.You can remove an element from the array and append it to the end of it.This is one MOVE and counted as one MOVE operation.Find the min no of moves required to sort the array.
回答1:
As I understand it, moving an element to the end shifts all elements after that one place, so that moving the third element of
[a_1, a_2, a_3, a_4, a_5, a_6]
to the end produces
[a_1, a_2, a_4, a_5, a_6, a_3]
If that understanding is correct, the strategy with the minimum number of moves is
- if the array is sorted, stop.
- find the smallest element that appears before a smaller element in the array
- move that element to the end
go to 1.
Ex: I/p: 8 6 1 7 5 2 3 9 Process: 8 6 1 7 2 3 9 5 8 1 7 2 3 9 5 6 8 1 2 3 9 5 6 7 1 2 3 9 5 6 7 8 1 2 3 5 6 7 8 9 -> sorted So totally 5 moves to be done to sort an array.
Proof: With each step, the initial sequence of elements of the final sorted array that are placed in ascending order in the array increases by at least one, therefore the algorithm terminates. The algorithm only terminates when the array is sorted.
Each array element is moved at most once. If element v
is moved in iteration i
, afterward all elements <= v
are placed in ascending order in the array. Moving any element > v
doesn't change that relative placing, therefore v
is not selected as the element to move in any later iteration.
An array element is moved if and only if it is at least as large as the first to be moved, say v_1
.
By construction, the moved elements form a strictly increasing sequence, thus no element < v_1
is moved.
After moving v_1
, all elements larger than v_1
are placed before a smaller element (namely v_1
, possibly others) in the array. The only way to change the relative placing of an element w > v_1
and v_1
afterward is by moving w
to the end, therefore at some step w
must be moved.
In any sorting sequence, all elements >= v_1
must be moved at least once:
v_1
must be moved in some step because there is a v_0 < v_1
placed after v_1
in the original array and the only way to change the order of v_0
and v_1
is moving v_1
.
By the above, all w > v_1
must be moved at least once after v_1
has been moved.
Finding the number of moves required can be done in O(n), but of course the sorting itself is quadratic.
After finding the first element to move, v_1
, one simply counts the number k
of elements smaller than v_1
, the required number of moves is then n - k
.
Finding v_1
in O(n): (I had originally thought forwards, which turned out to be backwards, if you go backwards, it is straightforward.)
First, you scan from the end of the array until you have found a local minimum or have reached the start of the array. If you reach the start, the array is already sorted, no moves required. Otherwise, store the value of the (local) minimum, and the value of the element directly before as the tentative value f v_1
. Then proceed further until you reached the start of the array, at each step updating the minimum if the current element is smaller, or the tentative v_1
if the current element is larger than the minimum but smaller than the tentative v_1
.
int move_count(int *a, int n) {
int j = n-1;
while(j > 0 && a[j-1] < a[j]) --j;
if (j == 0) return 0; // the array is already sorted
// min_val holds the smallest element in the array after
// the currently investigated position, v_1 holds the smallest
// element after the current position that is larger than any later
int min_val = a[j], v_1 = a[j-1];
j -= 2;
while(j >= 0) {
if (a[j] < min_val) {
min_val = a[j];
} else if (a[j] < v_1) {
v_1 = a[j];
}
--j;
}
int count_smaller = 0;
for(j = 0; j < n; ++j) {
if (a[j] < v_1) ++count_smaller;
}
return n - count_smaller;
}
回答2:
The solution would be based on selection sort. Take a look at this animation in http://www.sorting-algorithms.com/selection-sort to get the idea. The idea is simply to find the kth largest element in the kth iteration, and call MOVE on that element. Finding this element is also demonstrated in the animation. The complexity is O(n).
回答3:
If MOVE is the only way allowed to shift elements in the array, then Selection sort is the way to go with kth element MOVEd to the end and replaced with the kth smallest element in the kth iteration.
Min move operations = 0 (when array is already sorted).
Max move operations = n (when array is sorted in inverse order of the desired).
So, total move operations = O(n).
Complexity of the sorting algorithm is unchanged.
来源:https://stackoverflow.com/questions/11681114/min-no-of-moves-to-sort-an-array