Java 如何将PriorityQueue恢复到方法调用之前的初始状态?
我在做练习题 这个问题基本上是在PriorityQueue和某个k中传递,然后返回PriorityQueue中的第k个最小值。您还需要将PriorityQueue恢复到其初始状态,并可以使用一个堆栈或队列作为辅助数据结构 我更高层次的伪思维是,因为PriorityQueue已经充当了一个min堆,所以我真正需要做的(我的算法)是:Java 如何将PriorityQueue恢复到方法调用之前的初始状态?,java,algorithm,data-structures,priority-queue,Java,Algorithm,Data Structures,Priority Queue,我在做练习题 这个问题基本上是在PriorityQueue和某个k中传递,然后返回PriorityQueue中的第k个最小值。您还需要将PriorityQueue恢复到其初始状态,并可以使用一个堆栈或队列作为辅助数据结构 我更高层次的伪思维是,因为PriorityQueue已经充当了一个min堆,所以我真正需要做的(我的算法)是: 从PriorityQueue中删除k个元素 将第k个最小值存储为局部变量 将移除的k个元素推到堆栈上(堆栈以便我可以按相同顺序添加元素) 从堆栈中弹出所有元素,并将它
public int kthSmallest(PriorityQueue<Integer> pQ, int k) {
if(k <= 0 || k > pQ.size()) {
throw new IllegalArgumentException();
} else {
Stack<Integer> aux = new Stack<Integer>();
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;
}
}
。。。我的算法产生了正确的结果17,但它将优先级队列的状态更改为[-3,17,9,81,22,42]
,这是出乎意料的
我曾考虑复制PriorityQueue,但这违反了一个条件,“您可以使用一个堆栈或队列作为辅助数据结构”
如何恢复PriorityQueue的状态?在实现中需要调整两件事。首先,应该使用队列而不是堆栈作为辅助数据结构。将项目推入堆栈,然后将其弹出将导致它们以相反的顺序添加回优先级队列。如果它们以
1,2,3
的形式从优先级队列中出来,它们将以3,2,1
的形式添加回优先级队列。这是因为堆栈是后进先出的数据结构。您希望使用队列作为辅助数据结构,因为它是FIFO(先进先出)数据结构,所以它将保持相同的顺序
其次,只从优先级队列中拉出前k个元素。我建议您排空整个队列,这样您就可以按照元素出现的顺序将所有元素重新添加到队列中,而不仅仅是一些元素
换言之,我将对您的计划进行如下调整:
public int kthSmallest(PriorityQueue<Integer> pQ, int k) {
if(k <= 0 || k > pQ.size()) {
throw new IllegalArgumentException();
} else {
Queue<Integer> aux = new ArrayDeque<Integer>();
int kThSmallest = -1;
for(int c=0;c<pQ.size();c++){
Integer element = pQ.remove();
if(c == k-1)
kThSmallest = element;
aux.add(element);
}
while(!aux.isEmpty())
pQ.add(aux.remove());
return kThSmallest;
}
}
public int kths最小(优先队列pQ,int k){
如果(k pQ.size()){
抛出新的IllegalArgumentException();
}否则{
队列aux=new ArrayDeque();
int-kthsmalest=-1;
对于(int c=0;cHow是否确定PriorityQueue
的内部状态?保存删除的所有内容,并在退出前将其放回。是什么让您认为当前的解决方案错误?我认为它似乎是正确的。@kraskevich尝试在站点上运行代码,数组的状态会发生变化。如果通过调用toArray获得了哪个数组方法,它没有任何意义,因为PriorityQueue类的文档清楚地表明,元素没有特定的顺序返回。您是如何产生耗尽整个PriorityQueue的直觉的?LIFO对我来说是有意义的,因为您可以立即撤消该操作。就像您取出3,2,1一样。堆栈将是[3,2,1].弹出将撤消最近的操作我想我看的方式是PriorityQueue仍然是一个队列。如果你从队列中取出前k个人,并将他们放在队列的后面,你就修改了队列,而如果你将所有人都从队列中取出,并将他们全部放回队列中,你就没有…当然,只要你这样做了按顺序。但你要把它们放回行中。你要移除优先级最高的东西。放回会把它放回相同的位置,因为它仍然具有使其具有最高优先级的相同属性?我不确定为什么这个假设在你的情况下不起作用。对于常规数字,我同意,应该是这样的。但是,通常情况下,您会希望耗尽队列。想象一下,如果您有具有相同优先级但值不同的元素,例如按优先级排序的请假请求。Dan和Jim具有相同的优先级,因此他们具有相同的优先级。但是Dan首先提交了他的请求,因此应该在队列中更快。您希望dr因为排队,所以丹仍然领先于吉姆。这就是为什么我在这种情况下推荐它。啊,我知道如果你不排干,原始顺序将不会被保留。
public int kthSmallest(PriorityQueue<Integer> pQ, int k) {
if(k <= 0 || k > pQ.size()) {
throw new IllegalArgumentException();
} else {
Queue<Integer> aux = new ArrayDeque<Integer>();
int kThSmallest = -1;
for(int c=0;c<pQ.size();c++){
Integer element = pQ.remove();
if(c == k-1)
kThSmallest = element;
aux.add(element);
}
while(!aux.isEmpty())
pQ.add(aux.remove());
return kThSmallest;
}
}