泡咖啡问题

咖啡,问题 · 浏览次数 : 350

小编点评

**泡咖啡问题作者:Grey原文地址:博客园:泡咖啡问题CSDN:泡咖啡问题题目描述数组 arr 中记录每个咖啡机制造一杯咖啡的时间,假设有 m 个人,都在 0 号时间点开始排队,返回一个长度为 m 的数组,代表每个人得到咖啡的时间,要求:最后一个得到咖啡的人的时间尽可能短。** **主要思路:** 1. 建立一个小根堆,存储咖啡机的信息。 2. 在循环中,从数组中取出每个咖啡机的开始时间和制作一杯咖啡的时间,并将其添加到小根堆中。 3. 小根堆的比较策略是:咖啡机开始工作的时间加上这个咖啡机制作一杯咖啡的时间之和越小的在堆顶。 4. 每次做完一杯咖啡以后,弹出,记录下此时的时间存入结果数组,并修改此时的咖啡机的开始工作时间,再次压入小根堆。 5. 最后,返回结果数组。 **时间复杂度:**O(n log k),其中 n 是数组的大小,k 是咖啡机数量。 **代码:** ```java import java.util.PriorityQueue; public class Code_Coffee { public static class CoffeeMachine { @Override public String toString() { return "CoffeeMachine{" + "start=" + start + ", work=" + work + '}'; } public int start; public int work; } public static int[] bestChoices(int[] arr, int m) { int[] ans = new int[m]; PriorityQueue heap = new PriorityQueue<CoffeeMachine>((o1, o2) -> o1.start + o1.work - o2.start - o2.work); for (int coffeeWork : arr) { // 制造咖啡最短时间的咖啡机在堆顶 heap.add(new CoffeeMachine(0, coffeeWork)); } for (int i = 0; i < m; i++) { CoffeeMachine cur = heap.poll(); // 第i号人使用cur这个咖啡机,所以cur这个咖啡机的开始时间变为cur.start + cur.work System.out.println(i + " 号人使用 " + cur + "咖啡机"); ans[i] = cur.start + cur.work; System.out.println(i + " 号人在 [\" + cur.start + \"] 时刻搞定完一杯咖啡\"); cur.start = ans[i]; heap.add(cur); } return ans; } public static void main(String[] args) { int m = 5; int[] arr = {2, 3, 5}; bestChoices(arr, m); } } ``` **其他说明:** * 此代码假设咖啡机开始工作的时间是整数,如果时间是浮点数,需要对开始时间进行格式化。 * 此代码使用了小根堆来模拟咖啡机的排队过程,小根堆的比较策略可以确保在最后的那个人得到咖啡的时间尽可能短。

正文

泡咖啡问题

作者:Grey

原文地址:

博客园:泡咖啡问题

CSDN:泡咖啡问题

题目描述

数组 arr 中记录每个咖啡机制造一杯咖啡的时间,假设有 m 个人,都在 0 号时间点开始排队,返回一个长度为 m 的数组,代表每个人得到咖啡的时间,

要求:最后一个得到咖啡的人的时间尽可能短。

主要思路

定义咖啡机这个数据结构

    public static class CoffeeMachine {
       
        public int start;
        public int work;

        public CoffeeMachine(int s, int w) {
            start = s;
            work = w;
        }
        @Override
        public String toString() {
            return "CoffeeMachine{" + "start=" + start + ", work=" + work + '}';
        }

    }

其中

start 变量表示这个咖啡机什么时候可以空闲,

work 变量表示这个咖啡机制作一杯咖啡的时间,

接下来,设置一个小根堆(Java 中就是 PriorityQueue),小根堆存放的就是咖啡机的信息,小根堆的比较策略就是:咖啡机开始工作的时间加上这个咖啡机制作一杯咖啡的时间之和越小的在堆顶。

每次做完一杯咖啡以后,弹出,记录下此时的时间存入结果数组,并且修改此时的咖啡机的开始工作时间,再次压入小根堆,然后小根堆弹出下一个元素,如此往复,一直到小根堆弹出 m 个元素。

例如

image

首先把所有咖啡机放入小根堆,第一个弹出的咖啡机是 CoffeeMachine{start=0, work=2}

0 号小人使用 CoffeeMachine{start=0, work=2} 咖啡机

此时这个咖啡机的参数变为 CoffeeMachine{start=2, work=2}

把改变后的咖啡机放入小根堆,再次弹出一个咖啡机,此时

CoffeeMachine{start=0, work=3} 咖啡机被弹出

1 号人使用 CoffeeMachine{start=0, work=3} 咖啡机

此时这个咖啡机的参数变为 CoffeeMachine{start=3, work=3}

把改变后的咖啡机放入小根堆,再次弹出一个咖啡机,此时

CoffeeMachine{start=2, work=2} 咖啡机被弹出

2 号人使用 CoffeeMachine{start=2, work=2} 咖啡机

此时这个咖啡机的参数变为 CoffeeMachine{start=4, work=2}

把改变后的咖啡机放入小根堆,再次弹出一个咖啡机,此时

CoffeeMachine{start=0, work=5} 咖啡机被弹出

3 号人使用 CoffeeMachine{start=0, work=5} 咖啡机

此时这个咖啡机的参数变为 CoffeeMachine{start=5, work=5}

把改变后的咖啡机放入小根堆,再次弹出一个咖啡机,此时

CoffeeMachine{start=4, work=2} 咖啡机被弹出

4 号人使用 CoffeeMachine{start=4, work=2} 咖啡机

此时这个咖啡机的参数变为 CoffeeMachine{start=6, work=2}

完整代码如下


import java.util.PriorityQueue;

public class Code_Coffee {
    public static class CoffeeMachine {
        @Override
        public String toString() {
            return "CoffeeMachine{" + "start=" + start + ", work=" + work + '}';
        }

        public int start;
        public int work;

        public CoffeeMachine(int s, int w) {
            start = s;
            work = w;
        }

    }

    public static int[] bestChoices(int[] arr, int m) {
        int[] ans = new int[m];
        PriorityQueue<CoffeeMachine> heap = new PriorityQueue<>((o1, o2) -> o1.start + o1.work - o2.start - o2.work);
        for (int coffeeWork : arr) {
            // 制造咖啡最短时间的咖啡机在堆顶
            heap.add(new CoffeeMachine(0, coffeeWork));
        }
        for (int i = 0; i < m; i++) {
            CoffeeMachine cur = heap.poll();
            // 第i号人使用cur这个咖啡机,所以cur这个咖啡机的开始时间变为cur.start + cur.work
            System.out.println(i + " 号人使用 " + cur + "咖啡机");
            ans[i] = cur.start + cur.work;
            System.out.println(i + " 号人在 [" + cur.start + "] 时刻搞定完一杯咖啡");
            cur.start = ans[i];
            heap.add(cur);
        }
        return ans;
    }

    public static void main(String[] args) {
        int m = 5;
        int[] arr = {2, 3, 5};
        bestChoices(arr, m);
    }
}

更多

算法和数据结构笔记

与泡咖啡问题相似的内容: