【leetcode】任务调度器

【leetcode】任务调度器

题目:

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

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

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

示例 :

输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B.
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。

提示:

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

思路:

(1)先找出现次数最多的字母,假设为A,出现m次,要求字母间隔大于n。那么先将A按照给定间隔排好后的长度为(m-1)(n+1) + 1,(m-1)是因为m个A之间有(m-1)块空格。(n+1)是因为每块空格长度为n,在加上字母A,一共n+1,最后一个+1是最后一个字母A。比如字母A出现3次,间隔为2,则A排好后为
A _ _ A _ _ A
(2)接下来排的时候只需要依次将频率小的字母插入这些空格中,注意插的时候要先插满第二位的空格,再插第三位的空格,以此类推,且频率高的字母先插。
(3)上面说的是大部分情况,但是还会出现两种特殊情况:
3.1.最大频率的字母不止一个,比如A,B都出现了3次,则此时A,B排好后为AB _ _ AB _ _ AB
会发现此时长度多了一个长度(最后一个B的长度),因此此时的总长度应该为(m-1)
(n+1)+count ,count为最大频率的字母个数,在这里为2。上面的(1)可以认为是count=1的一个特例
3.2.当中间所有的空格都被填满了还没有插入所有元素,此时需要将剩余元素依次插入到每块的后面去(这样可以保证彼此间的间隔大于n,相当于是拓宽了部分块的间隔),比如AAABBCCD 先得到ABCABCA,此时还有一个D没有插入,则插到每个块后面去,得到ABCDABCA,此时会发现其实这个长度就是原数组的长度。

java代码:

class Solution {
    public int leastInterval(char[] tasks, int n) {
 
        Map<Character, Integer> map = new HashMap<>();
        int m = 0;
        for (char c : tasks) {
            if (map.containsKey(c)) {
                map.put(c, map.get(c) + 1);
            } else {
                map.put(c, 1);
            }
            m = Math.max(m, map.get(c));
        }
 
        int res = (m - 1) * (n + 1);  //第(1)种情况
 
        for (Map.Entry<Character, Integer> entry : map.entrySet()) {
            if (entry.getValue() == m) { //第(3)-1的情况,第一种中的+1是在这里加的
                res++;
            }
        }
 
        return Math.max(res, tasks.length); //第(3)-2的情况
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容