我在Integers的Java中有优先级队列:
PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
当我打电话时,pq.poll()
我得到了最小的元素。
问题:如何更改代码以获取最大元素?
我在Integers的Java中有优先级队列:
PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
当我打电话时,pq.poll()
我得到了最小的元素。
问题:如何更改代码以获取最大元素?
Answers:
这样吧:
PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder());
queue.offer(1);
queue.offer(2);
queue.offer(3);
//...
Integer val = null;
while( (val = queue.poll()) != null) {
System.out.println(val);
}
在Collections.reverseOrder()
提供了一个Comparator
将在元素进行排序PriorityQueue
在这种情况下,在该oposite为了自己的自然顺序。
Collections.reverseOrder()
也是比较器的重载,因此如果您比较自定义对象,它也可以工作。
PriorityQueue(Comparator<? super E> comparator)
。
从Java 8开始可以使用lambda表达式。
下面的代码将打印10个较大的代码。
// There is overflow problem when using simple lambda as comparator, as pointed out by Фима Гирин.
// PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);
PriorityQueue<Integer> pq =new PriorityQueue<>((x, y) -> Integer.compare(y, x));
pq.add(10);
pq.add(5);
System.out.println(pq.peek());
lambda函数将两个Integer作为输入参数,将它们彼此相减,然后返回算术结果。lambda函数实现功能接口Comparator<T>
。(这是就地使用的,与匿名类或离散实现相反。)
(x, y) -> y - x
由于溢出,类似的比较器可能不适用于长整数。例如,数字y = Integer.MIN_VALUE,而x = 5则得出正数。最好使用 new PriorityQueue<>((x, y) -> Integer.compare(y, x))
。虽然,@ Edwin Dalorzo可以使用更好的解决方案Collections.reverseOrder()
。
您可以提供一个自定义Comparator
对象,以相反的顺序对元素进行排名:
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(defaultSize, new Comparator<Integer>() {
public int compare(Integer lhs, Integer rhs) {
if (lhs < rhs) return +1;
if (lhs.equals(rhs)) return 0;
return -1;
}
});
现在,优先级队列将撤消其所有比较,因此您将获得最大元素而不是最小元素。
希望这可以帮助!
if (rhs < lhs) return +1;
if (rhs > lhs) return -1;
if (lhs < rhs) return +1; if (lhs > rhs) return -1;
PriorityQueue<Integer> pq = new PriorityQueue<Integer> (
new Comparator<Integer> () {
public int compare(Integer a, Integer b) {
return b - a;
}
}
);
b-a
可引起overflow
所以应避免使用它并应使用Collections.reverseOrder();
作为比较器或更换用Ba Integer.compare(a,b);
已经在添加Java 8
优先级队列的元素是根据其自然排序或在队列构建时提供的比较器进行排序的。
比较器应重写比较方法。
int compare(T o1, T o2)
默认比较方法将返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。
Java提供的Default PriorityQueue是Min-Heap,如果要最大堆,则代码如下
public class Sample {
public static void main(String[] args) {
PriorityQueue<Integer> q = new PriorityQueue<Integer>(new Comparator<Integer>() {
public int compare(Integer lhs, Integer rhs) {
if(lhs<rhs) return +1;
if(lhs>rhs) return -1;
return 0;
}
});
q.add(13);
q.add(4);q.add(14);q.add(-4);q.add(1);
while (!q.isEmpty()) {
System.out.println(q.poll());
}
}
}
参考:https : //docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#comparator()
这是Java中的Max-Heap示例:
PriorityQueue<Integer> pq1= new PriorityQueue<Integer>(10, new Comparator<Integer>() {
public int compare(Integer x, Integer y) {
if (x < y) return 1;
if (x > y) return -1;
return 0;
}
});
pq1.add(5);
pq1.add(10);
pq1.add(-1);
System.out.println("Peek: "+pq1.peek());
输出将是10
这可以通过Java 8中的以下代码实现,该代码引入了仅使用比较器的构造函数。
PriorityQueue<Integer> maxPriorityQ = new PriorityQueue<Integer>(Collections.reverseOrder());
将PriorityQueue更改为MAX PriorityQueue方法1:队列pq = new PriorityQueue <>(Collections.reverseOrder()); 方法2:队列pq1 = new PriorityQueue <>(((a,b)-> b-a); 让我们看几个例子:
public class Example1 {
public static void main(String[] args) {
List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
pq.addAll(ints);
System.out.println("Priority Queue => " + pq);
System.out.println("Max element in the list => " + pq.peek());
System.out.println("......................");
// another way
Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
pq1.addAll(ints);
System.out.println("Priority Queue => " + pq1);
System.out.println("Max element in the list => " + pq1.peek());
/* OUTPUT
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
......................
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
*/
}
}
让我们接受一个著名的访谈问题:使用PriorityQueue的数组中第K个最大元素
public class KthLargestElement_1{
public static void main(String[] args) {
List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
int k = 3;
Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
pq.addAll(ints);
System.out.println("Priority Queue => " + pq);
System.out.println("Max element in the list => " + pq.peek());
while (--k > 0) {
pq.poll();
} // while
System.out.println("Third largest => " + pq.peek());
/*
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
Third largest => 666
*/
}
}
其他方式 :
public class KthLargestElement_2 {
public static void main(String[] args) {
List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
int k = 3;
Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
pq1.addAll(ints);
System.out.println("Priority Queue => " + pq1);
System.out.println("Max element in the list => " + pq1.peek());
while (--k > 0) {
pq1.poll();
} // while
System.out.println("Third largest => " + pq1.peek());
/*
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
Third largest => 666
*/
}
}
我们可以看到,两者给出的结果相同。
我只是在两个堆的最小和最大堆上对两个比较器运行了蒙特卡洛仿真,它们都得到相同的结果:
这些是我使用的最大比较器:
(A)集合内置比较器
PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(Collections.reverseOrder());
(B)自定义比较器
PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(new Comparator<Integer>() {
int compare(Integer lhs, Integer rhs) {
if (rhs > lhs) return +1;
if (rhs < lhs) return -1;
return 0;
}
});
if (rhs < lhs) return +1;
(rhs> lhs)返回-1;
PriorityQueue<Integer> lowers = new PriorityQueue<>((o1, o2) -> -1 * o1.compareTo(o2));