min no of MOVES to sort an array?

时光怂恿深爱的人放手 提交于 2020-03-17 05:29:14

问题


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

  1. if the array is sorted, stop.
  2. find the smallest element that appears before a smaller element in the array
  3. move that element to the end
  4. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!