如何在方法调用之前将PriorityQueue恢复到其初始状态?

我正在做练习问题练习IT Kth Smallest

这个问题基本上是你在PriorityQueue和某个k中传递的,你将返回该PriorityQueue中的第k个最小值。 您还要将PriorityQueue还原到其初始状态,并可以使用一个堆栈或队列作为辅助数据结构。

我的更高级别的伪思想是因为PriorityQueue已经充当了一个最小堆,从Java PriorityQueue ,我真正需要做的就是(我的算法):

  1. 从PriorityQueue中删除k个元素

  2. 将第k个最小值存储为局部变量

  3. 将删除的k元素推送到堆栈(堆栈,以便我可以按相同的顺序添加元素)

  4. 弹出堆栈中的所有元素,然后将它们重新添加回PriorityQueue

  5. 返回第k个最小值

以下是执行所有操作的代码:

public int kthSmallest(PriorityQueue pQ, int k) { if(k  pQ.size()) { throw new IllegalArgumentException(); } else { Stack aux = new Stack(); int kThSmallest = -1; for(int c=0;c<k;c++){ int element = pQ.remove(); if(c == k-1) kThSmallest = element; aux.push(element); } while(!aux.isEmpty()) pQ.add(aux.pop()); return kThSmallest; } } 

当我运行程序时,我得到所有正确的输出,以kth最小,但我无法恢复我的PriorityQueue的状态。 例如,在传递PriorityQueue时:

 [-3, 9, 17, 22, 42, 81] with ak of 3 

…我的算法生成了正确的结果17,但它将PriorityQueue的状态更改为[-3, 17, 9, 81, 22, 42] ,这是意料之外的。

我想要制作PriorityQueue的副本,但是违反了一个条件,“你可以使用一个堆栈或队列作为辅助数据结构”。

我该如何恢复PriorityQueue的状态?

在您的实现中需要调整两件事。 首先,您应该使用队列而不是堆栈作为辅助数据结构。 将项目推入堆栈然后将其弹出将导致它们以相反的顺序添加回优先级队列。 如果它们从优先级队列中退出1, 2, 3 ,则它们将被添加回优先级队列,为3, 2, 1 。 这是因为堆栈是LIFO(后进先出)数据结构。 您希望将队列用作辅助数据结构,因为它是FIFO(先进先出)数据结构,因此它将保留相同的顺序。

其次,您只将第一个k元素拉出priorty队列。 我建议排空整个队列,这样你就可以按照它们出来的顺序将所有元素添加回队列,而不仅仅是一些。

换句话说,我会按如下方式调整你的程序:

 public int kthSmallest(PriorityQueue pQ, int k) { if(k <= 0 || k > pQ.size()) { throw new IllegalArgumentException(); } else { Queue aux = new ArrayDeque(); int kThSmallest = -1; for(int c=0;c 

注意:我将程序中的'element'变量从int类型更改为Integer 。 这与你的程序的正确性无关,但注意自动拳击是一个好习惯。 通用类型(如集合)使用盒装整数。 这是一个存储原始整数的对象。 将盒装整数分配给int类型的东西需要将其取消装箱,即转回int原语。 这不是什么大不了的事,除非您立即将此值重新添加回集合中。 由于你已经将它拆箱到一个原始的int ,它需要再次装箱回一个Integer ,这需要系统创建一个对象来存储它。因为你所做的所有事情都是把它从并将它放回集合中,最好在这里使用Integer值,以避免取消装箱和装箱值,因为它并不是真正需要的。