给定一个输入数组和sum,返回需要求和的最小元素

时间:2014-02-19 23:00:59

标签: java algorithm priority-queue binary-heap

问题是selection algorithm在选择最少数量的项目时的变化,其总和至少是某个值N.例如,您可能想要一个总和为5,000或更多的项目列表,但是您不需要比输入列表中的项目更多的项目。因此,如果一个数字是5,001,那么您的输出列表将包含一个数字。

另一个例子:Input list {3,4,5,1,2} target = {8}. output list will be : {5,3}

此问题已在excellent series of posts中使用binaryHeap解决; 但是当我在Java中实现时,我没有得到所需的输出。我得到了整个input list。 我无法找出问题的确切原因。这是我的代码;

public class SelectTopSum {
    public static void main(String[] args){
        int[] arr = {5,2,10,1,33};
        int target=33;

        System.out.println(Arrays.toString(selectTop(arr, target)));
    }

    private static int[] selectTop(int[] arr, int sum) {
        //get max heap
        PriorityQueue<Integer> pq = new PriorityQueue<>(10, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        int runningTot=0;

        for (int i : arr) {
            if (runningTot<sum) {
                runningTot+=i;
                pq.add(i);
            }
            else if (i > pq.peek()) {
                runningTot-=pq.remove();
                runningTot+=i;
                pq.add(i);
            }
            while (runningTot-pq.peek()>=sum) {
                runningTot-=pq.remove();
            }
        }

        //System.out.println("priority queue is "+ pq);

        int[] result=new int[pq.size()];
        int i=0;
        while (!pq.isEmpty()) {
            result[i]=pq.remove();
            i++;
        }
        return result;
    }
}

1 个答案:

答案 0 :(得分:2)

你的比较是错误的。

PriorityQueue最小的项目(基于您的比较)首先,并且通过说return o2.compareTo(o1);,您会看到最大的整数最小,但你需要的是最小的元素,而不是最大的元素。

您需要将其更改为:

return o1.compareTo(o2);

(请注意,我换了o1o2

或者,为了它的价值,你可以完全从构造函数中删除第二个参数,因为它将使用Integer.compareTo,这将做你想要的。