651.CPU 任务调度

621. Task Scheduler(Medium)
CPU 任务调度

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

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

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

Input: tasks = ["A","A","A","B","B","B"], n = 2
Output: 8
Explanation: A -> B -> idle -> A -> B -> idle -> A -> B.

解法一: 计算得到词频最大的字符,该字符相邻最大的数组偏移小于 n
通过 HashMap 统计词频,PriorityQueue 保证有序性

public int leastInterval(char[] tasks, int n) {
    Map<Character, Integer> freqs = new HashMap<>();
    for (int i = 0; i < tasks.length; i++)
        freqs.put(tasks[i], freqs.getOrDefault(tasks[i], 0) + 1);

    PriorityQueue<Map.Entry<Character, Integer>> pq = new PriorityQueue<>(
            (a,b) -> a.getValue() != b.getValue() ? b.getValue() - a.getValue() : a.getKey() - b.getKey());
    pq.addAll(freqs.entrySet());

    int count = 0;
    int maxFreq = pq.peek().getValue();
    while (!pq.isEmpty() && pq.peek().getValue() == maxFreq) {
        pq.poll();
        count ++;
    }
    return Math.max(tasks.length, (maxFreq - 1) * (n + 1) + count);
}

解法二: 通过 HashMap 统计原始词频, LinkedHash 根据 Map.Entry.getValue() 进行排序

public int leastInterval(char[] tasks, int n) {
    Map<Character, Integer> freqs = new HashMap<>();
    for (int i = 0; i < tasks.length; i++)
        freqs.put(tasks[i], freqs.getOrDefault(tasks[i], 0) + 1);

    freqs = sortByValue(freqs);
    int maxFreq = freqs.entrySet().iterator().next().getValue();
    int count = 0;
    for (Map.Entry<Character, Integer> entry : freqs.entrySet()) {
        if (entry.getValue() == maxFreq)
            count ++;
        else
            break;
    }
    return Math.max(tasks.length, (maxFreq - 1) * (n + 1) + count);
}

private Map<Character, Integer> sortByValue(Map<Character, Integer> map) {
    List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
    list.sort((o1, o2) -> !o1.getValue().equals(o2.getValue()) ? Integer.compare(o2.getValue(), o1.getValue()) : Character.compare(o1.getKey(), o2.getKey()));
    Map<Character, Integer> newMap = new LinkedHashMap<>();
    for (Map.Entry<Character, Integer> entry : list)
        newMap.put(entry.getKey(), entry.getValue());
    return newMap;
}
posted @ 2019-04-15 22:30  janh  阅读(145)  评论(0)    收藏  举报