当前位置: 首页 > 知识库问答 >
问题:

为my PriorityQueue实现自定义比较器

班承恩
2023-03-14

我试图解决以下leetcode问题:

给定一个排序数组,两个整数k和x,查找数组中与x最近的k个元素。结果也应该按升序排序。如果有一个领带,较小的元素总是首选。

示例1:输入:[1,2,3,4,5],k=4,x=3

产出:[1,2,3,4]

示例2:输入:[1,2,3,4,5],k=4,x=-1

产出:[1,2,3,4]

目前我的错误解决方案如下:

class Solution {
    public List<Integer> findClosestElements(int[] arr, int k, int x) {
        PriorityQueue<Integer> pq = new PriorityQueue<>(arr.length, (a,b) -> a == b ? a - b : Math.abs(a-x) - Math.abs(b-x));

       for(int i=0; i<arr.length; i++) {
           pq.add(arr[i]);

       }



        ArrayList ints = new ArrayList<>();

        for(int i=0;i<k;i++) {
            ints.add(pq.poll());


        }
        return ints;
    }
}

问题在于我传递给构造函数的比较器。其思想是,我希望我的比较器根据任何整数I和输入x之间的最小距离对整数进行排序,然后从队列中轮询k元素。我如何实现一个比较器函数,以这种方式对元素进行排序?

共有3个答案

金伟
2023-03-14

在您的实现中,您没有检查两个整数距离X相同的情况。
以下比较器实现将给出正确的结果:

PriorityQueue<Integer> pq = new PriorityQueue<>(arr.length, 
                (a,b) -> {
                    int comp = Integer.compare(Math.abs(a - x), Math.abs(b - x));
                    if(comp==0) {return Integer.compare(a, b);}
                    return comp;
                });
顾乐心
2023-03-14

在这里,问题不在于您的优先级队列,而是我们需要两个具有不同排序格式的结果。您的队列将给出前K个元素,但它永远不会按升序排列,因为它根据元素与“X”的距离排列元素,因此对于给定的X=4,元素3和5都在同一级别,因此您的结果将有像[4,3,5这样的数据]。

最好对结果列表进行单独排序。

执行集合。排序(整数)并返回结果。

常嘉平
2023-03-14

我会利用默认的Integer.compare方法。基本上,你想要的是首先检查绝对差异的比较,如果是平局,做一个正常的比较。

static int compare(int x, int a, int b) {
    int comp = Integer.compare(Math.abs(a - x), Math.abs(b - x));
    if (comp == 0) {
        return Integer.compare(a, b);
    }
    return comp;
}

这使得编写实际的优先级队列实现变得非常简洁

static List<Integer> findClosestElements(int[] arr, int k, int x) {
    PriorityQueue<Integer> queue = new PriorityQueue<>(
        arr.length, (a,b) -> compare(x, a, b));
    Arrays.stream(arr).forEach(queue::add);
    return queue.stream().limit(k).sorted().collect(Collectors.toList());
}
 类似资料:
  • 在我的PriorityQueue中,我有两种类型的客户,即VIP和常规客户。我想先为贵宾服务,再为常客服务。 如果CustomerID<100,则视为VIP。 如果客户是VIP,他会排在队列中VIP部分的最后 更新:我不想排序任何其他列除了VIP。我不想添加“日期”,因为它感觉像是一个黑客,而不是理解Java是如何工作的。

  • 我试着选一个段落,通过打印出前三个单词来找到它的“意义”。去掉所有语法单词和空白后,我使用Hashmap计算每个单词的出现次数。然后,由于我不知道更好的方法,我只是创建了自己的小自定义对象来存储单词、键和出现次数、值,就像Hashmap一样,但我的老师建议实现Comparable,但我遇到了一个问题。我有两个问题,一个在我“修复”另一个时出现。问题在于Pair类中的compareTo函数和另一个类

  • 我们正在使用firebase实时数据库,我正在考虑在本地实现一个缓存来减少重复调用。

  • 由于我对优先级队列的了解有限,所以我尝试实现它,但只能在asc或desc值xx中排序,这不是必需的。 我的方法是 请分享一些想法/方法。 看来很遗憾,我无法为我的情况提供所需的比较器。 不过,还是要在期待中感谢你

  • 我在理解和使用比较器方面有一个问题,有人问我以下问题: 我在一个单独的Employee类中使用compareTo比较器接口来调用比较器对象的重载使用。 任何帮助,建议,代码行将非常感谢!!

  • 下面的代码片段适用于条件1,但不适用于条件2。