给定一个不同整数的数组。你可以从数组中删除一个元素并将其附加到它的末尾。这是一个MOVE并计为一个MOVE操作。找到排序数组所需的最小移动数。
答案 0 :(得分:10)
据我了解,将元素移动到最后将所有元素移到该位置之后,以便移动
的第三个元素[a_1, a_2, a_3, a_4, a_5, a_6]
到最后产生
[a_1, a_2, a_4, a_5, a_6, a_3]
如果理解正确,那么移动次数最少的策略是
证明:对于每一步,最终排序数组的元素的初始序列在数组中按升序排列增加至少一个,因此算法终止。该算法仅在数组排序时终止。
每个数组元素最多移动一次。如果在迭代v
中移动元素i
,则之后所有元素<= v
将按升序排列在数组中。移动任何元素> v
不会改变相对位置,因此未选择v
作为在以后的任何迭代中移动的元素。
当且仅当数组元素至少与要移动的数组元素一样大时才移动,例如v_1
。
通过构造,移动的元素形成严格增加的序列,因此不会移动元素< v_1
。
移动v_1
后,所有大于v_1
的元素都放在数组中较小的元素(即v_1
,可能还有其他元素)之前。之后更改元素w > v_1
和v_1
的相对位置的唯一方法是将w
移至末尾,因此必须移动某个步骤w
。
在任何排序顺序中,所有元素>= v_1
必须至少移动一次:
v_1
必须在某个步骤中移动,因为在原始数组中v_0 < v_1
之后放置了v_1
,并且唯一的方法是更改v_0
和{的顺序{1}}正在移动v_1
。
如上所述,移动v_1
后,所有w > v_1
必须至少移动一次。
找到所需的移动次数可以在O(n)中完成,但当然排序本身是二次的。
找到要移动的第一个元素v_1
后,只需计算小于v_1
的元素的数量k
,然后所需的移动次数为v_1
。
在O(n)中找到n - k
:(我原本以为是前锋,后来证明是倒退,如果你倒退,则很简单。)
首先,从阵列末尾扫描,直到找到局部最小值或已到达阵列的开头。如果到达开头,则阵列已经排序,无需移动。否则,将(local)minimum的值和直接元素的值存储为暂定值f v_1
。然后继续前进,直到到达数组的开头,每一步更新当前元素更小的最小值,或者当前元素大于最小值但小于暂定{{1}时暂定v_1
}}
v_1
答案 1 :(得分:1)
解决方案将基于选择排序。在http://www.sorting-algorithms.com/selection-sort中查看此动画以获得想法。这个想法只是在第k次迭代中找到第k个最大元素,并在该元素上调用MOVE。在动画中也演示了查找此元素。复杂性是O(n)。
答案 2 :(得分:0)
如果MOVE是允许在数组中移位元素的唯一方法,则选择排序是将第k个元素MOVEd移到最后并用第k个迭代中的第k个最小元素替换的方式。
最小移动操作= 0(当数组已经排序时) 最大移动操作= n(当数组按所需的反向顺序排序时) 因此,总移动操作= O(n)。
排序算法的复杂性没有改变。