如何用最少的相邻元素交换对数组进行排序

时间:2019-04-05 06:46:15

标签: algorithm sorting mergesort

我有一个算法可以解决这个问题,教授必须按学生的班级得分对学生进行排序,好1分,差0分。在最小交换数中,只有相邻的学生可以交换。例如,如果按顺序[0,1,0,1]给学生,则只需要进行一次交换就可以进行[0,0,1,1],如果是[0,0,0,0,1,1, 1,1]不需要交换。

从问题描述中,我立即知道这是一个经典的最小相邻交换问题或计数反转问题,我们可以在合并排序中找到它。我尝试了自己的算法以及列出的herethis site,但没有一个通过所有测试。

当我尝试以相反的顺序对数组进行排序时,通过了最多数量的测试用例。我还尝试根据数组的第一个元素是0还是1来对数组进行排序。例如,第一个元素是1,那么我应该按降序对数组进行排序,否则学生可以按升序进行排序。在任何分组中,仍然没有任何效果。一些测试用例总是失败。问题是,当我以升序对它进行排序时,一个测试用例在反向排序的情况下失败了,而其他一些但不是全部都通过了。所以我不知道我在做什么错。

2 个答案:

答案 0 :(得分:0)

在我看来,术语“排序”在涉及0和1的数组时是一种夸张。您只需在O(n)中计数0和1即可产生输出。

为了解决“最小交换”部分,我构建了一个玩具示例;我想到了两个主意。所以,这个例子。我们正在为学生排序... f:

a b c d e f
0 1 0 0 1 1

a c d b e f
0 0 0 1 1 1

如您所见,这里没有太多排序。三个0,三个1。

首先,我将其框架为edit distance问题。即您只需使用“交换”操作即可将abcdef转换为acdbef。但是,您首先如何提出acdbef?我的假设是,您只需要将0和1拖到数组的相对侧,而不会干扰它们的顺序。例如:

        A     B     C     D
0 0 ... 0 ... 1 ... 0 ... 1 ... 1 1

0 0 0 0         ...         1 1 1 1
    A C                     B D

我不确定100%是否可行,是否确实会为您带来最少的交换。但这似乎是合理的-为什么您还要为e花额外的掉期费。 G。 A和C?

关于您应该将0放在第一个还是最后一个-我看不到两次运行相同算法并比较掉期数量的问题。

关于如何找到交换数量,甚至交换顺序-考虑编辑距离可以帮助您。仅查找交换数量也可以是编辑距离的简化形式。或者,也许更简单的方法-e。 G。找到最接近其“集群”的某物(0或1),然后将其移动。然后重复直到对数组进行排序。

答案 1 :(得分:-1)

如果我们必须在零之前对零进行排序,这将是简单的倒数计数。

def count(lst):
    total = 0
    ones = 0
    for x in lst:
        if x:
            ones += 1
        else:
            total += ones
    return total

由于在零之前对它们进行排序也是一种选择,因此我们只需要运行两次该算法,一次互换零和一的角色并取最小值即可。