这个问题来自一次采访:
在2个最大堆的并集中找到第k个最大元素,假设这个第k个元素出现在O(k log n)的两个堆中。
这是我提出的算法:
While k is not zero
if(root of max-heap #1 > root of max-heap #2)
{
extract-max(heap #1)
}
else if(root of max-heap #1 < root of max-heap #2)
{
extract-max(heap #2)
}
else //case of duplicates
{
extract-max(heap #1)
extract-max(heap #2)
}
k--
因此,当k = 0时,extract-max函数将提取第k个最大值。
我认为这个算法将在O(k log n)时间运行,因为extract-max操作将在O(log n)中运行,并且我执行k次。
这是正确的做法吗?似乎我没有使用给定的信息“这个第k个元素出现在两个堆中”?有没有更好的方法来利用这些信息?
答案 0 :(得分:0)
您的方法非常好,而且无法改进太多。它也有预期的复杂性,所以你应该好好去。只有我想到并且可以优化的是你只需要检查k是否为零,当你进入最后一种情况时:
While true
if(root of max-heap #1 > root of max-heap #2)
{
extract-max(heap #1)
}
else if(root of max-heap #1 < root of max-heap #2)
{
extract-max(heap #2)
}
else //case of duplicates
{
extract-max(heap #1)
extract-max(heap #2)
if (k == 1) {
break;
}
}
k--
通过这种方式,您可以减少平均情况下的比较次数(效果会非常轻微)。这也利用了您提供的附加信息 - 该元素对于两个堆都是通用的。但是,我不认为任何基准测试都会注意到这一改进,因为extract-max远远超过了比较的复杂性。