帮助新手使用Java堆应用程序

时间:2017-03-17 17:29:58

标签: java heap

在过去的4个小时里,我一直在努力学习这个学校作业。我对它们的工作原理有基本的了解,但由于某种原因,我在实现这个问题的想法上遇到了困难。我真的很感激一些反馈和提示,因为这似乎不是我自己的任何地方......

问题如下:我们有一个由整数表示的“机器”数组。整数表示机器制造产品所需的时间。我们还给出了一个整数,表示我们想要制造的产品数量。该任务是尽快制造给定数量的产品并返回所需的时间。

所以,例如:我们有机器[1,2,3,4],产品数量是10.答案应该是6,因为:

  • 在时间(0)我们“启动机器”(什么都不做)
  • 在时间(1),我们从机器1获得我们的第一个产品
  • 在时间(2)我们得到两个产品,从机器1和2,所以我们现在总共有3个
  • 在时间(3)我们得到两个产品,从机器1和3,加起来5
  • 在时间(4),我们得到三个产品,从机器1,2和4,总共加起来
  • 在时间(5)我们只从机器1获得一个产品,所以我们现在有9个
  • 在时间(6),我们从机器1获得我们的最后一个产品,并返回当前时间6

机器和产品的数量介于1..10 ^ 5之间。数组中的整数(机器的速度)介于1..10 ^ 9之间。

我已经设法解决了问题的工作代码,但它没有通过所有测试,因为它不够快。现在我已经尝试过使它更有效率的东西,但是这样做我只能设法打破整个事情或者让它变得更慢。例如,我尝试检查堆中的机器“速度”是否大于currentTime,然后结束循环以节省一些时间,但所做的只是让另一个测试超时(不明白为什么)。

public static long shortestTime(int[] machines, int amount) {

    PriorityQueue<Machine> heap = new PriorityQueue<Machine>();
    for (int i = 0; i < machines.length; i++) {
        heap.add(new Machine(machines[i]));
    }

    int currentTime = 0;  //Indicates how many time units have been used so far

    int timeOfNextProduct = -1;  //Tells the time when the next product(s) will be ready

    int numberOfNextProducts = 0;  //Keeps count of how many products will be ready at the next possible time any product can be finished

    int products = 0;  //Keeps count of the total number of products manufactured

    while (products < amount) {

        //We raise the current time by one
        currentTime++;

        //We check the next possible time for a product to be ready
        if (timeOfNextProduct == -1) {
            ArrayList<Machine> polled = new ArrayList();
            int i = heap.size();
            for (int j = 0; j < i; j++) {
                if (j == 0) {
                    timeOfNextProduct = heap.peek().getManufactureSpeed() + currentTime - 1;
                }
                Machine machine = heap.poll();
                if (timeOfNextProduct % machine.getManufactureSpeed() == 0) {
                    numberOfNextProducts++;
                }
                polled.add(machine);
            }
            for (int j = 0; j < polled.size(); j++) {
                heap.add(polled.get(j));
            }
        }

        //If there are products ready at current time, we add them to the 
        //integer "products" and reset the value of "timeOfNextProduct"
        if (currentTime == timeOfNextProduct) {
            products += numberOfNextProducts;
            if (products >= amount) {
                return currentTime;
            }
            timeOfNextProduct = -1;
            numberOfNextProducts = 0;
        } else {
            //We jump straight to the next interesting time
            //(minus 1 since we add 1 to currentTime in the beginning of the loop
            currentTime = timeOfNextProduct - 1;
        }

    }

    return currentTime;

}

public static void main(String[] args) {
    System.out.println(shortestTime(new int[]{1, 2, 3, 4}, 10));  //Prints out 6
}

public class Machine实现了Comparable {

private int manufactureSpeed;

public Machine(int manufactureSpeed) {
    this.manufactureSpeed = manufactureSpeed;
}

public int getManufactureSpeed() {
    return manufactureSpeed;
}

@Override
public int compareTo(Machine t) {
    if (this.manufactureSpeed < t.manufactureSpeed) {
        return -1;
    }
    return 1;
}

}

1 个答案:

答案 0 :(得分:0)

您使用优先级队列的方式是问题的根源。

这里使用优先级队列的重点是知道机器何时完成生产。

因此,您应该让机器知道时间,让机器知道它的生产时间,然后根据机器产生的东西制作比较功能。

这样你就可以从队列的前面取出那些产生某些东西的机器,并将它们放回到后面。