【问题标题】:Bubble sort variant - three adjacent number swapping冒泡排序变体 - 三个相邻的数字交换
【发布时间】:2018-04-08 13:16:13
【问题描述】:

这个问题出现在 Code jam 2018 资格赛已经结束。
https://codejam.withgoogle.com/2018/challenges/(问题2)

问题描述:

标准冒泡排序算法的基本操作是检查一对相邻的数字,如果左边的数字大于右边的数字,则反转该对。但是我们的算法检查一组三个相邻的数字,如果最左边的数字大于最右边的数字,它会反转整个组。因为我们的算法是“三元冒泡排序”,所以我们简称为Trouble Sort。

我们期待在特别节目中展示麻烦排序 夏威夷分拣兴趣小组会议,但我们的实习生之一 刚刚指出了一个问题:Trouble Sort 有可能 没有正确排序列表!以列表 8 9 7 为例。

我们需要您的帮助进行进一步的研究。给定一个列表 N 整数,确定故障排序是否会成功排序 以非递减顺序排列。如果没有,请查找索引 (从 0 开始计数)的第一个排序错误后 算法已经完成:即第一个大于的值 算法完成后紧随其后的值。

因此,一种天真的方法是对给定列表应用故障排序,对列表应用正常排序,然后找到第一个不匹配元素的索引。但是,对于非常大的 N,这会超时。

这是我的想法: 该算法会将第 0 个索引与第 2 个、第 2 个与第 4 个等进行比较。 类似地,第 1 和第 3、第 3 和第 5 等等。

奇数索引处的所有元素将根据奇数索引进行排序。偶数索引元素也是如此。 所以问题在于两个连续的奇数/偶数索引元素之间。

如果不使用 O(n^2) 方法,我想不出办法。

我的方法可行吗,还是有更简单的方法?

【问题讨论】:

标签: algorithm sorting


【解决方案1】:

你的观察是正确的。问题陈述中提出的算法只会比较(和交换)它们之间的连续奇偶元素。

如果您进一步观察,您可以说故障排序是一种算法,可以正确地对数组内部的奇数和偶数索引元素进行排序。 (即好像数组 A 的奇数索引元素和偶数索引元素是两个独立的数组 B 和 C)

换句话说,Trouble Sort 确实对 B 和 C 进行了正确排序。这里的问题是奇偶索引元素的数组 B 和 C 是否可以正确合并。您应该检查对奇数和偶数索引元素进行排序是否足以使整个数组排序。

这一步真的很像 MergeSort 的合并步骤。唯一的区别是,由于索引是您操作的限制因素,您始终知道将从哪个数组中选择顶部元素。对于一个索引为 1 的数组 A,在 B 和 C 的合并步骤中,在每个步骤中,您应该从 B 中选择 previous unpicked 最小的元素,然后是 C。

所以,基本上,如果你使用诸如合并排序或堆排序之类的算法对 B 和 C 进行排序,O(NlogN),然后以上一段中描述的方式将它们合并,这需要 O(N),你结束在经过故障排序算法处理后,与数组 A 的版本相同。

不同之处在于时间复杂度。虽然故障排序需要O(N^2) 时间,但上述操作需要O(NlogN) 时间。一旦你最终得到这个数组,那么你可以检查O(N)时间,如果对于每个连续的索引 i、j、A[i] < A[j] 成立。算法的整体复杂度仍为O(NlogN)

下面是 Python 中的代码示例,用于演示我上面描述的算法的某种伪代码。由于 Python 数组是 0 索引的,因此在实现上存在一些细微差别。你可以观察到这段代码的执行here

def does_trouble_sort_work(A):
    B, C = A[0::2], A[1::2]
    B_sorted = sorted(B)
    C_sorted = sorted(C)
    j = k = 0
    for i in xrange(len(A)):
        if i % 2 == 0:
            A[i] = B_sorted[j]
            j += 1
        else:
            A[i] = C_sorted[k]
            k += 1 

    trouble_sort_works = True
    for i in xrange(1, len(A)):
        if A[i-1] > A[i]:
            trouble_sort_works = False
            break
    return trouble_sort_works

【讨论】:

  • 优雅的描述。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 2012-07-14
  • 1970-01-01
  • 2023-03-24
  • 2015-04-10
  • 2014-03-06
相关资源
最近更新 更多