621. 任务调度器

题目描述

给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。

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

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

解法

其实就是贪心算法,每次选择当前能选择的任务中个数最多的那种任务执行。但是我用优先队列做有一个用例过不了。另外优先队列想要每次peek都是优先级最大的值的话,它的Comparator必须是((a,b)->(b.priority - a.priority))。但其实这种做法还是稍微有点复杂。看了评论区有大佬做的很简单,是直接用数学公式计算的,https://leetcode-cn.com/problems/task-scheduler/solution/jian-ming-yi-dong-de-javajie-da-by-lan-s-jfl9/

class Solution {
    /**
     * 621.任务调度器
     *
     * @param tasks 任务列表
     * @param n 同种任务之间的执行间隔
     * @return 执行完所有任务需要的最短时间
     */
    public int leastInterval(char[] tasks, int n) {
        int interval = n;
        //当前可执行的任务队列
        PriorityQueue<Task> execuable = new PriorityQueue<>();//某种任务剩余得越多优先级越高
        Set<Character> allTasks = new HashSet<>();
        Map<Character, Task> map = new HashMap<>();
        initExecuable(tasks, allTasks, execuable, map);
        int res = 0;
        while (!allTasks.isEmpty()) {
            res++;
            if (!execuable.isEmpty()) {
                Task tmp = execuable.peek();
                tmp.cooldown = n+1;//执行后有冷却
                execuable.remove(tmp);
                tmp.num--;//执行完任务数-1
                if (tmp.num == 0) {
                    allTasks.remove(tmp.task);
                }
            }

            //执行完一个任务之后更新其他种类任务得状态
            for (Character a : allTasks) {
                Task task = map.get(a);
                if (task.cooldown != 0 ) {
                    task.cooldown--;
                    if (task.cooldown == 0) {
                        execuable.add(task);
                    }
                }
            }
        }
        return res;
    }

    public void initExecuable(char[] tasks, Set<Character> allTasks, PriorityQueue<Task> execuable, Map<Character, Task> map) {
        for (char a : tasks) {
            if (allTasks.add(a)) {
                map.put(a, new Task(a, 1, 0));
                execuable.add(map.get(a));
            } else {
                map.get(a).num++;
            }
        }
    }

    class Task implements Comparable{
        char task;
        public int cooldown;//该种任务的剩余冷却时间冷却
        public int num;//该种任务还剩多少个

        public Task(char task, int num, int cooldown) {
            this.task = task;
            this.num = num;
            this.cooldown = cooldown;
        }

        @Override
        public int compareTo(Object o) {
            if (o instanceof Task) {
                return  ((Task) o).num - this.num;
            } else {
                throw new RuntimeException();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值