贪心-优先队列-模拟-任务调度器

2020-03-10 17:22:21

问题描述:

给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。

然而,两个相同种类的任务之间必须有长度为 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。

你需要计算完成所有任务所需要的最短时间。

示例 1:

输入: tasks = ["A","A","A","B","B","B"], n = 2
输出: 8
执行顺序: A -> B -> (待命) -> A -> B -> (待命) -> A -> B.

注:

任务的总个数为 [1, 10000]。
n 的取值范围为 [0, 100]。

问题求解:

解法一:贪心

从数据规模可以看出时间复杂度应该是O(n) / O(nlogn)。很容易想到的是要先将频率计算出来,并且按照频率进行排序,频率最高的字符至少会占用(freq_max - 1) * (n + 1) + 1个时间周期。

如果有k个频率均为最高,那么上述的公式就变成了(freq_max - 1) * (n + 1) + k,在这种情况下,低频率的字符完全放入了中间的空当中,甚至还会有盈余。

那么还有一种情况就是,中间的空档并不够放置所有剩余的字符,那么此时最终的解就是len(tasks),因为剩余的字符可以任意的插入不同slot的末尾,并且保证空闲是足够的。

算法时间复杂度:O(nlogn)

    public int leastInterval(char[] tasks, int k) {
        int n = tasks.length;
        int[] freq = new int[26];
        for (char c : tasks) freq[c - 'A'] += 1;
        Arrays.sort(freq);
        int idx = 25;
        while (idx >= 0 && freq[idx] == freq[25]) idx -= 1;
        int common = 25 - (idx + 1) + 1;
        return Math.max(n, (freq[25] - 1) * (k + 1) + common);
    }

  

解法二:优先队列

本题除了上述的贪心解法,还可以使用优先队列去模拟结果,使用优先队列的解更加直观。我们每次从队列中取k + 1个最多的任务去做,全部任务都执行完成即可。

时间复杂度:O(time) 和最终的任务序列长度有关。

    public int leastInterval(char[] tasks, int k) {
        int n = tasks.length;
        int[] freq = new int[26];
        for (char c : tasks) freq[c - 'A'] += 1;
        PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
        for (int i = 0; i < 26; i++) if (freq[i] != 0) pq.add(freq[i]);
        int res = 0;
        while (!pq.isEmpty()) {
            List<Integer> temp = new ArrayList<>();
            for (int i = 0; i <= k; i++) {
                if (!pq.isEmpty()) {
                    if (pq.peek() > 1) {
                        temp.add(pq.peek() - 1);
                    }
                    pq.poll();
                }
                res += 1;
                if (pq.isEmpty() && temp.size() == 0) break;
            }
            for (Integer i : temp) pq.add(i);
        }
        return res;
    }

  

 

posted @ 2020-03-10 17:30  hyserendipity  阅读(342)  评论(0编辑  收藏  举报