Java 理解优先级队列比较器
学习一些DP和遇到PQ用作某些问题的堆,但是知道比较器射击手lamdas在我的头脑中变得很难找到清晰 例如:Java 理解优先级队列比较器,java,comparator,priority-queue,Java,Comparator,Priority Queue,学习一些DP和遇到PQ用作某些问题的堆,但是知道比较器射击手lamdas在我的头脑中变得很难找到清晰 例如: class Interval { int start = 0; int end = 0; Interval(int start, int end) { this.start = start; this.end = end; } } PriorityQueue<Integer> maxStartHeap = new PriorityQueue
class Interval {
int start = 0;
int end = 0;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
}
PriorityQueue<Integer> maxStartHeap = new PriorityQueue<>(n, (i1, i2) -> intervals[i2].start - intervals[i1].start);
PriorityQueue<Integer> maxEndHeap = new PriorityQueue<>(n, (i1, i2) -> intervals[i2].end - intervals[i1].end);
类间隔{
int start=0;
int end=0;
间隔(整数开始,整数结束){
this.start=start;
this.end=end;
}
}
PriorityQueue maxStartHeap=新的PriorityQueue(n,(i1,i2)->间隔[i2]。开始-间隔[i1]。开始);
PriorityQueue maxEndHeap=new PriorityQueue(n,(i1,i2)->interval[i2]。end-interval[i1]。end);
一个int减去另一个int如何创建所需的最小或最大第一顺序?我想尝试一下可能的实现,但不知道从哪里开始。有人能给我指出一个资源,它可以解释到底发生了什么,因为比较器的外观,如果它看起来是基于最大的负数是最优先的,但这只是一个猜测
完整性的完整代码:
import java.util.*;
class Interval {
int start = 0;
int end = 0;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
}
class NextInterval {
public static int[] findNextInterval(Interval[] intervals) {
int n = intervals.length;
// heap for finding the maximum start
PriorityQueue<Integer> maxStartHeap = new PriorityQueue<>(n, (i1, i2) -> intervals[i2].start - intervals[i1].start);
// heap for finding the minimum end
PriorityQueue<Integer> maxEndHeap = new PriorityQueue<>(n, (i1, i2) -> intervals[i2].end - intervals[i1].end);
int[] result = new int[n];
for (int i = 0; i < intervals.length; i++) {
maxStartHeap.offer(i);
maxEndHeap.offer(i);
}
// go through all the intervals to find each interval's next interval
for (int i = 0; i < n; i++) {
int topEnd = maxEndHeap.poll(); // let's find the next interval of the interval which has the highest 'end'
result[topEnd] = -1; // defaults to -1
if (intervals[maxStartHeap.peek()].start >= intervals[topEnd].end) {
int topStart = maxStartHeap.poll();
// find the the interval that has the closest 'start'
while (!maxStartHeap.isEmpty() && intervals[maxStartHeap.peek()].start >= intervals[topEnd].end) {
topStart = maxStartHeap.poll();
}
result[topEnd] = topStart;
maxStartHeap.add(topStart); // put the interval back as it could be the next interval of other intervals
}
}
return result;
}
public static void main(String[] args) {
Interval[] intervals = new Interval[] { new Interval(2, 3), new Interval(3, 4), new Interval(5, 6) };
int[] result = NextInterval.findNextInterval(intervals);
System.out.print("Next interval indices are: ");
for (int index : result)
System.out.print(index + " ");
System.out.println();
intervals = new Interval[] { new Interval(3, 4), new Interval(1, 5), new Interval(4, 6) };
result = NextInterval.findNextInterval(intervals);
System.out.print("Next interval indices are: ");
for (int index : result)
System.out.print(index + " ");
}
}
import java.util.*;
课间休息{
int start=0;
int end=0;
间隔(整数开始,整数结束){
this.start=start;
this.end=end;
}
}
NextInterval类{
公共静态int[]findnexterval(间隔[]间隔){
int n=间隔。长度;
//用于查找最大起始值的堆
PriorityQueue maxStartHeap=新的PriorityQueue(n,(i1,i2)->间隔[i2]。开始-间隔[i1]。开始);
//用于查找最小端点的堆
PriorityQueue maxEndHeap=new PriorityQueue(n,(i1,i2)->interval[i2]。end-interval[i1]。end);
int[]结果=新的int[n];
for(int i=0;i=间隔[topEnd].end){
int topStart=maxStartHeap.poll();
//找到最接近“开始”的间隔
而(!maxStartHeap.isEmpty()&&interval[maxStartHeap.peek()].start>=interval[topEnd].end){
topStart=maxStartHeap.poll();
}
结果[topEnd]=topStart;
maxStartHeap.add(topStart);//将间隔放回原位,因为它可能是其他间隔的下一个间隔
}
}
返回结果;
}
公共静态void main(字符串[]args){
区间[]区间=新区间[]{新区间(2,3),新区间(3,4),新区间(5,6)};
int[]result=NextInterval.findnexterval(间隔);
System.out.print(“下一个间隔索引为:”);
for(int索引:结果)
系统输出打印(索引+“”);
System.out.println();
区间=新区间[]{新区间(3,4),新区间(1,5),新区间(4,6)};
结果=NextInterval.FINDNEVERVAL(间隔);
System.out.print(“下一个间隔索引为:”);
for(int索引:结果)
系统输出打印(索引+“”);
}
}
与此类似:
new PriorityQueue<>(n, new Comparator<Integer>() {
public int compare(Integer one, Integer two) {
return intervals[one] - intervals[two];
}
});
这将根据Interval#difference
的相应值对值进行排序。如果您在Java8上仍然有点落后,我将进一步研究函数api和方法引用。另请参见:.中的
基于优先级堆的无限优先级队列。优先级队列的元素根据其自然顺序进行排序,或者由队列构造时提供的比较器进行排序,具体取决于所使用的构造函数。优先级队列不允许空元素。依赖自然排序的优先级队列也不允许插入不可比较的对象(这样做可能会导致ClassCastException)。
此队列的头是相对于指定顺序的最小元素。如果多个元素以最小值绑定,则头部就是这些元素之一——绑定被任意断开。队列检索操作轮询、移除、查看和元素访问队列头部的元素
当您想要存储没有自然排序的元素时,您可以让它们实现Comparable
接口,或者将比较器传递给构造函数。递增/递减顺序取决于比较器的行为。
此方法通过返回整数指示比较结果。如果两个对象相等,则将对象A
与对象B
进行比较必须返回0
,如果对象A>对象B
,则返回<0
的整数,如果对象A
,则返回的整数
如果您遵循此例程,优先级队列将按递增顺序存储项目,即最小的项目将位于头部。如果您想将最大的项目存储在队列的最前面,那么比较器应该反向工作,例如,当对象A>对象B
时,不要返回>0
的整数,当对象A
时,返回<0
的整数
如果您的队列存储整数,inta-intb
将在a>b
时返回0
,在a==b
时返回0
,在a
时返回<0
,这就是它工作的原因。您可以返回int b-int a
以反转优先级队列的顺序。“一个int减去另一个int如何创建所需的最小或最大第一顺序?”——比较器和可比文档返回负数意味着a
,返回零意味着a==b
,返回正数意味着a>b
。如果将a
和b
设为整数,则a-b
将给出一个数字wh
class Interval {
//...
public int difference() {
return this.end - this.start;
}
}
PriorityQueue<Interval> values = new PriorityQueue((i1, i2) -> Integer.compare(i1.difference(), i2.difference()));
//AKA
PriorityQueue<Interval> values = new PriorityQueue(Comparator.comparingInt(Interval::difference)));