找到k个最小的奇数

时间:2013-10-19 10:30:15

标签: algorithm divide-and-conquer

实际上,我在教自己算法,在这里我试图解决这个问题,如下:

我们有一个以任意顺序排列的n个正整数的数组,并且我们有k> k> = 1到n。问题是输出k个最小的奇数。如果 A中的奇数整数小于k,我们应该报告所有奇数。例如, 如果A = [2,17,3,10,28,5,9,4,12,13,7]和k = 3,则输出应为3,5,9。 我想在O(n)时间内解决这个问题。

我目前的解决方案是让另一个数组只有奇数,然后我应用这个算法,找到中位数并将列表分成L,中,右,并将k比作如下:

If |L|<k<= (|L|+|M|) Return the median 
else if K<|L|, solve the problem recursively on (L)
else work on (R, k- (|L|+|M|) 

感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

假设输出可以是任何顺序:

创建一个只有奇数的单独数组。

使用selection algorithm确定第k项。一个这样的算法是quickselect(平均在O(n)中运行),它与快速排序有关 - 它通过一些枢轴对数组进行分区,然后递归地转到其中一个分区边,基于每个的大小。有关详细信息,请参阅this question

由于quickselect对输入进行分区,因此您可以在运行此算法后直接输出结果(如上所述Karoly)。

上述两个步骤均采用O(n),因此整体运行时间为O(n)

如果您需要按升序输出:

如果k = n,并且所有数字都是奇数,那么O(n)解决方案就是O(n)排序算法,但是没有人知道这样的算法。

对于那些考虑不同意的人,说某些非基于比较的排序是O(n) - 它不是,这些算法中的每一个都有其他复杂因素,例如数字的大小。

您可以使用Proger's answerO(n + k log n))中建议的方法使用heapk)中建议的方法,或者通过输入进行迭代,保持{{3}} { {1}}最小的奇数(O(n log k))。