数据结构与算法之队列: Leetcode 621. 任务调度器 (Typescript版)

这篇具有很好参考价值的文章主要介绍了数据结构与算法之队列: Leetcode 621. 任务调度器 (Typescript版)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

任务调度器

  • https://leetcode.cn/problems/task-scheduler/

描述

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

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

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

示例 1:

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

示例 2:

输入:tasks = ["A","A","A","B","B","B"], n = 0
输出:6
解释:在这种情况下,任何大小为 6 的排列都可以满足要求,因为 n = 0
["A","A","A","B","B","B"]
["A","B","A","B","A","B"]
["B","B","B","A","A","A"]
...
诸如此类

示例 3:

输入:tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
输出:16
解释:一种可能的解决方案是:
     A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A

提示:

  • 1 <= task.length <= 1 0 4 10^4 104
  • tasks[i] 是大写英文字母
  • n 的取值范围为 [0, 100]

算法实现

1 )方案 1

function leastInterval(tasks: string[], n: number): number {
    let result = '' // 最终队列执行的结果
    const dict = {} // 对归类进行存储
    tasks.forEach((item) => {
        dict[item] ? (dict[item] ++) : (dict[item] = 1)
    })
    while(true) {
        // 任务清单
        const keys = Object.keys(dict)
        // 任务处理完毕跳出
        if (!keys.length) {
            break
        }
        // 正常处理过程
        let tmp = [] // 用于存储 1 + n个任务单元
        for (let i = 0; i <= n; i++) {
            let max:number = 0 // 找到最大的任务
            let key:string
            let pos:number
            // 遍历任务清单
            keys.forEach((item, idx) => {
                // 当前任务数量大于max
                if (dict[item] > max) {
                    max = dict[item] // 存储更新max
                    key = item // 存储更新当前任务
                    pos = idx // 存储更新当前任务下标索引,用于后续的删除操作
                }
            })
            // 没有匹配到key, 直接跳出此次循环
            if (!key) {
                break
            }
            // 找到了key
            tmp.push(key) // 临时队列添加当前的key
            keys.splice(pos, 1) // 将当前key从任务队列中删除
            dict[key] -- // 更新key的长度,已消费完成,删除来更新剩余个数
            // 当全部消费完成,移除当前的任务
            if (dict[key] < 1) {
                delete dict[key]
            }
        }
        result += tmp.join('').padEnd(n + 1, '-') // 如果不全,补充冷却时间
    }
    // 边界的处理, 最后不要出现冷却时间
    result = result.replace(/-+$/, '')
    return result.length
}
  • 关键需求分析:
    • 两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间
    • 因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
    • 要求,完成所有任务的最短时间
  • 从上面的描述和示例中可见
    • 队列中有A,B,C,…, 现在开启了一个任务
    • 如果当前开启了A任务,那接下来n个的任务中不能有A了
    • 如果其他任务不够n的长度,那么要冷却等待
    • 只要现在队列中还有任务,我就要处理任务本身和n个任务冷却时间的 n+1 的任务,
    • 也就是从队列中取出这些任务来存放,求最短的存放时间
      • 如何做到最短,考虑使用最多的任务优先处理,尽量不会有剩余,交叉着来
      • 少的来进行插缝作业,这样即保证少的任务使用了
      • 又保证多的任务不会用冷却时间处理来占用更多资源
  • 这个算法,在实现上效率不高

2 )方案 2文章来源地址https://www.toymoban.com/news/detail-433660.html

function leastInterval(tasks: string[], n: number): number {
  // 初始化一个矩阵,用于存储给定任务的数量的字典
  const cnts = Array(26).fill(0);
  for(const c of tasks) {
    cnts[c.charCodeAt(0) - 'A'.charCodeAt(0)]++;
  }
  // 统计出任务中对多的数量
  let max = 0, tot = 0;
  for (let i = 0; i < 26; i++) {
    max = Math.max(max, cnts[i]);
  }
  // 更新tot变量的值,用于统计具有最多执行次数的任务数量
  for (let i = 0; i < 26; i++) {
    tot += max === cnts[i] ? 1 : 0;
  }
  // 这里是最核心的算法
  return Math.max(tasks.length, (n + 1) * (max - 1) + tot)
};
  • 这是官方示例,效率很高
  • 这里用到charCodeAt() 方法可返回指定位置的字符的 Unicode 编码
  • 后续有时间再研究下:https://leetcode.cn/problems/task-scheduler/solution/ren-wu-diao-du-qi-by-leetcode-solution-ur9w/ 中的方法二:构造

到了这里,关于数据结构与算法之队列: Leetcode 621. 任务调度器 (Typescript版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】如何设计循环队列?图文解析(LeetCode)

    LeetCode链接:622. 设计循环队列 - 力扣(LeetCode) 目录 做题思路 只开辟 k 个空间 多开一个空间 代码实现 1. 循环队列的结构 2. 开辟空间 3. 判断空 4. 判断满 5. 队尾插入数据 6. 队头删除数据 7. 获取队头元素 8. 获取队尾元素 9. 销毁队列 全部代码 设计循环队列,使用数组或链表

    2024年02月10日
    浏览(42)
  • 【LeetCode】621.任务调度器

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

    2024年02月09日
    浏览(21)
  • 【数据结构】如何用队列实现栈?图文详解(LeetCode)

    LeetCode链接:225. 用队列实现栈 - 力扣(LeetCode) 本文默认读者已经掌握栈与队列的基本知识 或者先看我的另一篇博客:【数据结构】栈与队列_字节连结的博客-CSDN博客 由于我们使用的是C语言,不能直接使用队列的操作, 所以做这道题得先把我们之前实现的队列复制过来:

    2024年02月12日
    浏览(37)
  • 【数据结构】如何用栈实现队列?图文解析(LeetCode)

    LeetCode链接:232. 用栈实现队列 - 力扣(LeetCode) 注:本文默认读者已掌握栈与队列的基本操作 可以看这篇文章熟悉知识点:【数据结构】栈与队列_字节连结的博客-CSDN博客 目录 做题思路 代码实现 1. MyQueue 2. myQueueCreate 3. myQueuePush 4. myQueuePeek 5. myQueuePop 6. myQueueEmpty 7. myQueueF

    2024年02月11日
    浏览(32)
  • 【LeetCode】【数据结构】栈与队列必刷OJ题

    👀 樊梓慕: 个人主页   🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言: 【LeetCode】20.有效的括号(栈的括号匹配问题) 【LeetCode】225.用队列实现栈 【LeetCode】232.用栈实现队列 【LeetCo

    2024年02月13日
    浏览(42)
  • 【数据结构和算法】--队列的特殊结构-循环队列

    循环队列是队列的一种特殊结构,它的 长度是固定的 k ,同样是 先进先出 ,理论结构是 首尾相连的环形循环结构 。其理论结构大致如下: 具体结构描述可以参考 LeetCode : 622. 设计循环队列的题目要求,大致如下: 设计你的循环队列实现。 循环队列是一种 线性数据结构 ,

    2024年02月04日
    浏览(45)
  • 队列——“数据结构与算法”

    各位CSDN的uu们你们好呀,又好久不见啦,最近有点摆烂,甚是惭愧!!!!今天,小雅兰的内容是队列,下面,让我们进入队列的世界吧!!! 队列 队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIF

    2024年02月06日
    浏览(44)
  • 算法与数据结构-队列

      队列跟栈一样,也是一种操作受限的线性表数据结构。不过,队列是先进者先出。   栈只支持两个基本操作:入栈 push()和出栈 pop()。队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取

    2024年02月12日
    浏览(43)
  • 数据结构与算法:队列

    在上篇文章讲解了栈之后,本篇也对这一章进行收尾,来到队列! 队列(Queue)就像是排队买票的人群。想象一下你去电影院看电影,人们在售票窗口形成一条线(队列)等待购票。队列遵循一个很重要的原则:先来先服务(First In, First Out,简称FIFO)。这意味着最先到达并

    2024年02月22日
    浏览(47)
  • 【数据结构和算法】--队列

    队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有 先进先出 FIFO(First In First Out) 的原则。 入队列 :进行 插入操作的一端称为队尾 。 出队列 :进行 删除操作的一端称为队头 。 队列结构联想起来也非常简单,如其名,队列就相当于

    2024年02月05日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包