仅使用交换函数基于父数组对给定数组进行排序

时间:2013-02-06 18:24:01

标签: algorithm

这是一个编码面试问题。我们会给出一个数组random_arr,我们需要使用 交换函数对其进行排序。

random_arr中每个元素的交换次数也是有限的。为此,您将获得一个数组parent_arr,其中包含random_arr每个元素的互换次数。

约束:

  1. 您应该使用交换功能。
  2. 每个元素可以重复最少5次,最多26次。
  3. 您不能将给定数组的元素设为0。
  4. 你不应该写辅助功能。
  5. 现在我将解释如何声明parent_arr。如果parent_arr如下:

    parent_arr [] = {a,b,c,d,...,z}然后

    a can be swapped at most one time.
    
    b can be swapped at most two times.
    

    如果parent_arr [] = {c,b,a,....,z}则

    c can be swapped at most one time.
    
    b can be swapped at most two times.
    
    a can be swapped at most three times
    

    我的解决方案:

    对于random_arr []中的每个元素,如果它已经排序,那么它下面有多少个元素。现在从parent_arr []中选择具有最小交换计数的元素,并检查它是否存在于random_arr []中。如果是,如果发生了多次,那么它将有多个位置可以放置。现在选择具有最大交换计数的位置(相当于该位置的元素)并交换它。现在减少该元素的交换计数并对parent_arr []进行排序并重复该过程。

    但效率很低,无法证明其正确性。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

首先,让我们简化你的算法;然后让我们非正式地证明它的正确性。

修改算法

观察一旦计算出排序序列中每个数字下面的元素数量,就有足够的信息来确定排序数组中每个相等元素组x的位置。例如,如果c重复7次并且前面有21个元素,那么c将占用范围[21..27](所有索引都是从零开始的;范围包括它的目的)。

按照互换次数增加的顺序浏览parent_arr。对于每个元素x,找到其目标范围rb的开头;还要注意其目标范围re的结束。现在,浏览random_arr范围的[rb..re] 元素。如果您看到x,请将其交换到范围内。交换后,增加rb。如果您发现random_arr[rb]等于x,请继续递增:这些x已经在正确的位置,您不需要交换它们。

正确性的非正式证明

现在让我们证明上述的正确性。观察一旦元素交换到它的位置,它永远不会再移动。当您到达x中的元素parent_arr时,已经处理了掉期数较少的所有元素。通过构造算法,这意味着这些元素已经到位。假设xk个允许的掉期数。当你将它交换到它的位置时,你会移出另一个元素。

此替换元素不能为x,因为在查找目标范围x中的目标时,算法会跳过[rb..re]。此外,被替换的元素不能是x parent_arr下的元素之一,因为x下面的所有元素都已经存在,因此无法移动。这意味着替换元素的交换计数必须为k+1或更多。由于到我们完成处理x时,我们已经耗尽了任何元素上的k掉期(这很容易通过归纳证明),我们换出的任何元素都为{{1}腾出空间至少有一个剩余的交换,当我们按照x指示的顺序到达时,我们可以将它交换到位。