Change priorityQueue to max priorityqueue
我在Java整数中有优先级队列:
1 | PriorityQueue<Integer> pq= new PriorityQueue<Integer>(); |
当我调用
问题:如何更改代码以获取最大元素?
这样吧:
1 2 3 4 5 6 7 8 9 10 | 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); } |
从Java 8开始就可以使用lambda表达式。
下面的代码将打印10,更大的代码。
1 2 3 4 5 6 7 8 | // 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函数实现功能接口
您可以提供一个自定义
1 2 3 4 5 6 7 |
现在,优先级队列将撤消其所有比较,因此您将获得最大元素而不是最小元素。
希望这可以帮助!
1 2 3 4 5 6 7 |
在Java 8+中,您可以通过以下方法之一创建最大优先级队列:
方法1:
1 |
方法2:
1 | PriorityQueue<Integer> maxPQ = new PriorityQueue<>((a,b) -> b - a); |
方法3:
1 | PriorityQueue<Integer> maxPQ = new PriorityQueue<>((a,b) -> b.compareTo(a)); |
优先级队列的元素根据其自然顺序或在队列构建时提供的比较器进行排序。
比较器应重写比较方法。
1 | int compare(T o1, T o2) |
默认比较方法将返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。
Java提供的Default PriorityQueue是Min-Heap,如果要最大堆,则代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 8中的以下代码来实现,该代码引入了仅使用比较器的构造函数。
1 |
这是Java中的Max-Heap示例:
1 2 3 4 5 6 7 8 9 10 11 |
输出将是10
将PriorityQueue更改为MAX PriorityQueue
方法1:队列pq = new PriorityQueue <>(Collections.reverseOrder());
方法2:队列pq1 = new PriorityQueue <>(((a,b)-> b-a);
让我们看几个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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个最大元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 */ } } |
其他方式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 */ } } |
我们可以看到,两者给出的结果相同。
您可以使用
这是文档。代替
这可以通过使用
1 |
您可以尝试类似:
1 |
哪个适用于您可能拥有的任何其他基本比较功能。
我们可以通过创建实现Comparator接口的CustomComparator类并覆盖其compare方法来做到这一点。下面是相同的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import java.util.PriorityQueue; import java.util.Comparator; public class Main { public static void main(String[] args) { PriorityQueue<Integer> nums = new PriorityQueue<>(new CustomComparator()); nums.offer(21); nums.offer(1); nums.offer(8); nums.offer(2); nums.offer(-4); System.out.println(nums.peek()); } } class CustomComparator implements Comparator<Integer>{ @Override public int compare(Integer n1, Integer n2){ int val = n1.compareTo(n2); if(val > 0) return -1; else if(val < 0) return 1; else return 0; } } |
1 | PriorityQueue<Integer> lowers = new PriorityQueue<>((o1, o2) -> -1 * o1.compareTo(o2)); |
我只是对两个比较器的双堆最小最小值进行了蒙特卡洛仿真,结果都相同:
这些是我使用的最大比较器:
(A)集合内置比较器
1 |
(B)自定义比较器
1 2 3 4 5 6 7 |
您可以尝试使用带有反向符号的元素。例如:添加a = 2&b = 5,然后轮询b = 5。
1 2 3 4 | PriorityQueue<Integer> pq = new PriorityQueue<>(); pq.add(-a); pq.add(-b); System.out.print(-pq.poll()); |
轮询队列的开头后,请反转符号以供使用。
这将打印5(较大的元素)。可以在幼稚的实现中使用。绝对不是可靠的解决方案。我不推荐。