我正在尝试找出一种算法,以查找数字列表中最高的两个数字。
最高的数字可以在n-1个阶段中找到,可能是通过冒泡排序的第一步或类似方法完成。对我而言,似乎在总共1.5n次比较中也可以找到下一个最高的数字。
我的教授布置了作业,要求我们编写一种算法,在n+log(n)次比较中找到最高的两个数字。这是否可能?有什么想法和建议吗?
编辑:当我说n + log(n)时,我不是指O(n + log n),而是确切地n + log n。
我正在尝试找出一种算法,以查找数字列表中最高的两个数字。
最高的数字可以在n-1个阶段中找到,可能是通过冒泡排序的第一步或类似方法完成。对我而言,似乎在总共1.5n次比较中也可以找到下一个最高的数字。
我的教授布置了作业,要求我们编写一种算法,在n+log(n)次比较中找到最高的两个数字。这是否可能?有什么想法和建议吗?
编辑:当我说n + log(n)时,我不是指O(n + log n),而是确切地n + log n。
编辑:糊涂大意地错过了一个简单的事情。这个解决方案是不正确的,尽管我仍然保留它,因为它仍然是avg(n+log(n))。感谢ShreevatsaR指出我的愚蠢。我确实考虑了树搜索,但完全忽略了回溯查找第二高的数字的想法,以log(n)的时间复杂度。
无论如何,以下是我证明这个劣质算法不超过平均n+log n的原因。在现实生活中,它应该仍然表现得相当好。
为了证明它的平均值为n+log n,我们只需证明第一次比较平均只成功了log(n)次。这是相当容易看到或证明的。
for each listOfNumbers as number
if number > secondHighest
if number > highest
secondHighest = highest
highest = number
else
secondHighest = number
O(2n)
个比较,这比O(n+log(n))
要大。 - Dominic RodgerO
,希望我的评论有意义。(即 2n
次比较比 n + log(n)
次比较更多) - Dominic Rodger伪代码(这不基本上就是n吗?)
int highestNum = 0
int secondHighest = highestNum
for(i = 0; i < list.length; i++)
{
if(list[i] >= highestNum)
{
secondHighest = highestNum
highestNum = list[i]
}
}
ShreevatsaR发布的答案似乎是O(n log n)。
第一次遍历(n个操作)会产生n/2个答案。通过重复,我猜你的意思是你将执行n/2个操作以产生n/4个答案。您将通过循环log n次。这很像归并排序,只是归并排序每次始终处理n个节点。它也运行循环log n次。我不明白这个算法如何跟踪第二高的数字。
nickf给出了正确的答案。最坏情况是列表已排序,它将进行2n次比较-即O(n)。
顺便说一句,O(n + log n)是O(n),阶符号指最坏情况渐近增长。