我正在为即将到来的考试而学习,我遇到了一个问题,我必须从传入的无限数字流中构建和维护前10个最高整数。我以为我可以使用固定大小为10的最小堆,并且,当我收到一个新号码时,我可以检查最小值是否低于新传入号码,如果是,我必须更新堆通过顺序提取根直到我得到一个更高的值,然后插入新的数字,以及先前弹出的根(减去第一个,以保持固定大小10)。现在我有了这个堆,我可以通过弹出并打印堆中的每个节点轻松获得前10名。
我用Java编写了一个方法,用一个PriorityQueue来完成我所说的。
public void addNumber(int number){
if(pq.size() < 10){
pq.offer(number);
}
else if(pq.peek() < number){
List<Integer> topNumbers = new LinkedList<Integer>();
while(!pq.isEmpty() && pq.peek() < number){
topNumbers.add(pq.poll());
}
pq.offer(number);
for(int i = 1; i < topNumbers.size(); i++){
pq.offer(topNumbers.get(i));
}
}
}
public void printTop10(){
List<Integer> topNumbers = new LinkedList<Integer>();
while(!pq.isEmpty()){
topNumbers.add(pq.poll());
}
for(int i = 0; i < topNumbers.size(); i++){
Node thisOne = topNumbers.get(topNumbers.size() - 1 - i);
System.out.println(thisOne);
pq.offer(thisOne);
}
}
根据我的测试,此代码完成工作并按预期工作。现在,我的问题来了。这两个操作的复杂性是什么?我们有一个PriorityQueue,因此insert和extract-min操作是对数的。但在这种情况下,堆的大小“n”最多为10.这是否意味着复杂性为O(log 10),这基本上是恒定的O(1)时间?
答案 0 :(得分:1)
是;常数的对数也是不变的。
通常,通过将运行时描述为多个变量的函数来分析此类算法。例如,我们可能会说您的算法在O(n log k)时间和O(k)空间中从k
个数字中提取顶部n
。
但是,如果知道k
的值,我们也可以使用这个事实来简化我们的分析。