检查排序数组需要移动多少个元素的最佳方法是什么?

时间:2019-07-13 04:57:34

标签: java arrays

假设我有一个数组[1、2、4、5、3]。在此数组中,如果要对数组进行排序,则3、4和5不会处于它们应处于的位置。如何检查有多少元素不在正确的位置?

我能想到的最快方法是将值复制到临时数组,对数组进行排序,然后比较哪些索引具有不同的值。那将是一个O(nlogn)解决方案。在O(n)中有什么方法可以做到吗?

2 个答案:

答案 0 :(得分:3)

  

那将是一个O(nlogn)解决方案。在O(n)中有什么方法可以做到吗?

否。

这是一个非正式证明。

假设存在一种算法A,该算法可以发现数组中所有位置不正确的元素都比O(nlogn)好。还要假设A告诉您每个元素的正确位置是什么。这意味着您可以按以下方式对数组进行排序:

    list_of_moves = A(array);
    for move in list_of_moves:
       apply move

(这里有一个故意的“手浪”,因为移动不是简单的交换。但是在O(m)中有简单的算法可以做到这一点。例如,考虑“时钟耐心”。)

我们认为AO(n)。移动步骤也将是O(m),其中m是移动数...,小于或等于n。因此,我们现在有一个 general 排序算法,即O(n + m)。那是与O(n)相同的复杂度类。

但是,有数学证明O(nlogn)是常规排序算法的下界。 (有关证明的说明,请参见https://www.bowdoin.edu/~ltoma/teaching/cs231/spring14/Lectures/6-moresorting/sortLB.pdf。)

矛盾!

因此,具有这些属性A 的算法O(n)


另一种选择是,(假设的)算法A会(准确地)告诉您哪些元素位于错误的位置,而不是它们的正确位置。

我认为这也是不可能的,但是我现在没有证据。


请注意,这与检查元素是否有序不同。这在O(n)中很容易做到。

问题在于,乱序元素仍然可以位于正确的位置。例如:

  1, 4, 3, 2

3乱序,但位置正确。在完全排序的数组中,3将处于现在的位置。 2和4将被切换。

答案 1 :(得分:-1)

您可以进行for循环,并检查下一个数组索引值是否大于之前的值。

int x = 0;

for (int i = 0; i < array.length - 1; i++)
{
    if (array[i+1] > array [i])
    {
         x++;
    }
}

x将是不按顺序排列的元素数