这个问题出现在代码堵塞2018资格回合中已经结束 https://codejam.withgoogle.com/2018/challenges/(问题2)
问题描述:
标准气泡排序算法的基本操作是检查一对相邻的数字,如果左边的数字大于正确的数字则反转该对。但是我们的算法检查一组三个相邻的数字,如果最左边的数字大于最右边的数字,它会反转整个组。因为我们的算法是"三元组冒泡排序",我们将其命名为麻烦排序。
我们期待在Special上展示Trouble Sort 兴趣小组在夏威夷排序会议,但我们的实习生之一 刚刚指出了一个问题:麻烦排序有可能 没有正确排序列表!例如,考虑清单8 9 7。
我们需要你的帮助进行进一步的研究。给出N的列表 整数,确定麻烦排序是否会成功排序 列入非递减顺序。如果不能,找到索引 (从0开始计数)之后的第一个排序错误 算法已完成:即大于的第一个值 算法完成后直接出现的值。
因此,一种天真的方法是对给定列表应用麻烦排序,对列表应用常规排序,并找到第一个不匹配元素的索引。但是,这对于非常大的N来说会超时。
以下是我的想法: 算法将第0个索引与第2个,第2个和第4个进行比较,依此类推。 同样地,第一个是第三个,第三个是第五个,依此类推。
奇数索引处的所有元素将根据奇数索引进行排序。对于偶数索引元素也是如此。 所以问题在于两个连续的奇数/偶数索引元素。
我无法想办法在不采用O(n ^ 2)方法的情况下解决问题。
我的方法是否可行,或者有更容易的事情?
答案 0 :(得分:0)
您的观察结果正确。问题陈述中提出的算法只比较(和交换)它们之间连续的奇数和偶数元素。
如果你更进一步观察,你可以说麻烦排序是一种算法,可以正确地对数组中奇数和偶数索引的元素进行排序。 (即,好像数组A的奇数索引元素和偶数索引元素是两个独立的数组B和C)
换句话说,麻烦排序可以正确排序B和C.这里的问题是奇数和偶数索引元素的数组B和C是否可以正确合并。你应该检查它们之间对奇数和偶数索引元素的排序是否足以使整个数组排序。
此步骤与MergeSort的合并步骤非常相似。唯一的区别是,由于索引是操作的限制因素,您始终知道从哪个数组中选择顶部元素。对于1索引数组A,在B和C的合并步骤中,在每个步骤中,您应该从B中选择最小的先前未取消的元素,然后选择C.
所以,基本上,如果你使用诸如mergesort或heapsort之类的算法对B和C进行排序,O(NlogN)
,然后以前一段中描述的方式合并它们,这需要{{1}在麻烦排序算法处理后,你最终得到了相同版本的数组A.
不同之处在于时间复杂性。虽然故障排序需要O(N)
时间,但上述操作需要O(N^2)
时间。一旦你最终得到这个数组,那么你可以检查O(NlogN)
时间,如果,对于每个连续索引i,j,O(N)
成立。算法的总体复杂性仍为A[i] < A[j]
。
下面是Python中的代码示例,用于演示上述算法的伪代码。由于Python数组被索引为0,因此在实现方面存在一些细微差别。您可能会观察到此代码here的执行情况。
O(NlogN)