我正在为fun / Java实践做以下问题:
编写一个方法
kthSmallest
,它接受PriorityQueue
个整数作为输入,并输出kth
最小整数。 传入的优先级队列的内部状态不应通过方法更改。您可以仅使用一个队列或堆栈作为额外数据。不允许其他数据结构。k
是1索引的(k = 1
表示最小值)。
获取kth
元素很简单:只删除k
次,因为它是优先级队列。我想我可以弹出,将元素放在堆栈上进行存储,然后在完成后将它们添加回队列。但这不起作用,因为元素在优先级队列中的排序方式不同。
这是好奇心的代码:
public int kthSmallest(PriorityQueue<Integer> pq, int k) {
Stack<Integer> s = new Stack<Integer>();
for (int i = 1; i <= k; ++i) {
s.push(pq.remove());
}
int kthValue = s.peek();
while (!s.empty()) {
pq.add(s.pop());
}
return kthValue;
}
那么如何在保持优先级队列的内部状态的同时做到这一点呢?
P.S。 - 您可以自己查看问题here
答案 0 :(得分:2)
您无法保证基础状态的任何内容:PriorityQueue
所具有的唯一命令概念是您在创建时指定的Comparator
提供的概念(或其自然顺序)元件)。您作为用户除此之外什么都不知道,并且它确实不应该有任何区别如何元素存储,只要队列的行为符合基于其规范的预期
答案 1 :(得分:1)
你为什么要搬家?无需修改传入的数据结构,这就是您的算法失败的原因。这只不过是ITERATOR / VISITOR。您需要做的就是遍历队列并维护一个最小数字的列表/数组。
另请注意,您假设队列中的第k个最小整数与优先级中删除的数字相同并不一定正确。优先级队列!=堆。在这种情况下,我可能有一个整数优先级队列,每个整数都有一个优先级字段。
class Node<Integer>
Integer data;
int priority;
}
class PriorityQueue {
List<Node> nodes;
Integer getHighestPriority() {
int maxPriorityIndex = 0;
for(int i=0; i< nodes.size(); i++) {
if(n.priority > maxPriority) {
maxPriorityIndex = nodes.get(i);
}
return nodes.get(maxPriorityIndex);
}
}
答案 2 :(得分:0)
已经说明了很多提示,我会简短地回答一下:
您正在使用来自给定对象的方法调用,您没有任何知识。你不知道是否使用了一个奇怪的比较器来比较队列中的整数(比如一个比较器说,所有的东西都是相同的,并且总是返回0)。这就是为什么你在任何情况下都不应该修改给定的对象(就像你使用poll / add一样)。
在这种情况下,要解决此问题,您可以使用缓冲区对象(如问题中所述,队列或堆栈(我使用类似给定队列的队列)来使用您选择的比较器并缓冲它将您的给定队列添加到缓冲区对象。
my solution at pastebin因为我没有任何剧透标签: - (