数据结构与算法之队列: LeetCode 621. 任务调度器 (Ts, Py, Go版)

使用 SolidJS 和 TypeScript 构建任务跟踪器 映剪辑纯净版App,新手入门级剪辑软件,做视频简单如手机P图!SolidJS 正迅速成为 Web 开发社区关注的焦点。凭借其直接的状态管理、细粒度的响应性和高性能,SolidJS 已成为其他 JavaScript 框架的基础。SolidJS 是 React 开发人员一直要求的一切,在本文中,我将引导您使用 SolidJS 构建任务跟踪器。我们将涵盖以下主题:为什么选择 SolidJS?使用 TypeScript 设置 SolidJS 应用程序。 阅读详情

任务调度器

  • 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","C","A","B","D","B"], n = 1
输出:6

解释:一种可能的序列是:A -> B -> C -> D -> A -> B。
由于冷却间隔为 1,你可以在完成另一个任务后重复执行这个任务。

示例 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 <= 10410^4104
  • tasks[i] 是大写英文字母
  • n 的取值范围为 [0, 100]

Typescript 版算法实现

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

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/ 中的方法二:构造

Python3 版算法实现

1 )方案 1

import re

class Solution:
    def leastInterval(self, tasks: List[str], n: int) -> int:
        result = ''  # 最终队列执行的结果
        dict = {}  # 对归类进行存储
        # 对列表进行归类,存储在字典里
        for task in tasks:
            if task in dict:
                dict[task] += 1
            else:
                dict[task] = 1
        
        while True:
            # 任务清单
            keys = list(dict.keys())
            if(len(keys) == 0): break
            tmp = []  # 用于存储 1 + n个任务单元
            # 注意这里是 n + 1
            for _ in range(n + 1):
                max = 0
                key = None
                pos = 0
                # 遍历任务清单
                for idx, item in enumerate(keys):
                    # 当前任务清单
                    if (dict[item] > max):
                        max = dict[item] # 存储更新当前max
                        key = item # 更新存储当前任务
                        pos = idx # 存储更新当前任务下标索引,用于后续的删除操作
                # 没有匹配到key, 直接跳出此次循环
                if key == None: break
                # 找到了 key
                tmp.append(key) # 临时队列添加当前的key
                # 移除
                del keys[pos]
                # keys.pop(pos) 或这样删除
                dict[key] -= 1 # 更新key的长度,已消费完成,删除来更新剩余个数
                # 当全部消费完成,移除当前的任务
                if dict[key] < 1:
                    del dict[key]
            # 使用 join 方法连接列表中的字符串
            result_str = ''.join(tmp)
            result += result_str[::-1].rjust(n + 1, '-')[::-1]
        # 边界的处理, 最后不要出现冷却时间
        result = re.sub(r'-+$', '', result)
        return len(result)

2 ) 方案2

class Solution:
    def leastInterval(self, tasks: List[str], n: int) -> int:
        # 初始化一个矩阵,用于存储给定任务的数量的字典
        cnts = [0] * 26
        for c in tasks:
            cnts[ord(c) - ord('A')] += 1

        # 统计出任务中对多的数量
        max_cnt = max(cnts)

        # 更新 tot 变量的值,用于统计具有最多执行次数的任务数量
        tot = sum(1 for cnt in cnts if cnt == max_cnt)

        # 这里是最核心的算法
        return max(len(tasks), (n + 1) * (max_cnt - 1) + tot)

Golang 版算法实现

1 )方案 1

func leastInterval(tasks []byte, n int) int {
    var result string // 最终队列执行的结果
    dict := make(map[string]int) // 对归类进行存储
    for _, item := range tasks {
        // 将 item 转换为字符串类型
        item := string(item)
        if val, ok := dict[item]; ok {
            dict[item] = val + 1
        } else {
            dict[item] = 1
        }
    }
    // 无限循环
    for {
        // 任务清单
        var keys []string
        for key := range dict {
            keys = append(keys, key)
        }
        // 任务处理完毕跳出
        if len(keys) == 0 {
            break
        }
        // 正常处理过程
        tmp := make([]string, 0) // 用于存储 1 + n 个任务单元
        // 在这里添加任务处理逻辑
        for i := 0; i <= n; i++ {
            maxVal := 0  // 找到最大的任务
            var key string
            var pos int
            // 遍历任务清单
            for idx, item := range keys {
                // 当前任务数量大于 maxVal
                if dict[item] > maxVal {
                    maxVal = dict[item]  // 存储更新 maxVal
                    key = item           // 存储更新当前任务
                    pos = idx            // 存储更新当前任务下标索引,用于后续的删除操作
                }
            }
            // 没有匹配到 key,直接跳出此次循环
            if key == "" {
                break
            }
            // 找到了 key
            tmp = append(tmp, key)     // 临时队列添加当前的 key
            keys = append(keys[:pos], keys[pos+1:]...)  // 将当前 key 从任务队列中删除
            dict[key]--                // 更新 key 的长度,已消费完成,删除来更新剩余个数
            // 当全部消费完成,移除当前的任务
            if dict[key] < 1 {
                delete(dict, key)
            }
        }
        result += strings.Join(tmp, "") + strings.Repeat("-", n+1-len(tmp))
    }
    result = strings.TrimRight(result, "-")
    return len(result)
}

2 )方案 2

import (
    "math"
)

func leastInterval(tasks []byte, n int) int {
    // 初始化一个数组,用于存储给定任务的数量的字典
    cnts := make([]int, 26)
    for _, c := range tasks {
        cnts[c-'A']++
    }

    // 统计出任务中对多的数量
    maxCnt := 0
    for _, cnt := range cnts {
        if cnt > maxCnt {
            maxCnt = cnt
        }
    }

    // 更新 tot 变量的值,用于统计具有最多执行次数的任务数量
    tot := 0
    for _, cnt := range cnts {
        if cnt == maxCnt {
            tot++
        }
    }

    // 这里是最核心的算法
    return int(math.Max(float64(len(tasks)), float64((n+1)*(maxCnt-1)+tot)))
}
MiniMax-M2+CodeX:面向高压编码场景的本地化AI编程协同方案 AI编程辅助已从‘能否生成代码’迈入‘能否在真实工程约束下持续输出高信噪比代码’的新阶段。其核心原理在于将大模型的泛化能力与开发者私有上下文深度耦合,通过AST感知建模提升语法确定性,借助本地化插件工作流实现规范对齐与测试驱动闭环。这种人机协同范式显著降低重复劳动损耗,释放工程师在架构设计与逻辑创新上的认知带宽,特别适用于算法竞赛、紧急交付、遗留系统重构等时间敏感、容错率低的硬核编码场景。MiniMax-M2与CodeX组合正是这一技术路径的典型实践。 阅读详情

相关推荐

数据结构课设 任务调度的合理性 (拓扑排序)

5-18 任务调度的合理性   (25分) 假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行。“任务调度”包括一组子任务、以及每个子任务可以执行所依赖的子任务集。 比如完成一个专业的所有课程学习和毕业设计可以看成一个本科生要完成的一项工程,各门课程可以看成是子任务。有些课程可以同时开设,比如英语和C程序设计,它们没有必须先修

Benjamin_Z的博客 3055

任务调度

SQL Server 内置系统调度算法采用:非抢占式争用CPU资源和主动退让策略,主动退让(voluntarily yield)是指在调度器(Scheduler)上运行的Worker都是以非抢占模式来争用CPU资源的。Worker 会一直在一个Scheduler上运行,直到运行结束,或者主动将Scheduler 让出给其他Worker为止。SQL Se...

weixin_33755847的博客 198

清华数据结构任务调度AC100

这里要注意以下几点: 1.由于是不超过8位的字符串,因此在构造字符串的时候应当保证是char xx[9];如果不是9,是别的话,那么字符数组会装不下,这样会导致最终的结果出现问题。这种情况已经发生过很多次了,应当注意+小心! 2. 由于优先级是0&lt;x&lt;2^32,因此,int整型是装不下的。因此需要使用long long int 型的变量。然而,在使用了long long int型的...

hgtjcxy的博客 2192

数据平台任务调度-策略设计

大数据平台任务调度策略设计时需要考虑的因素以及调度平台的核心工作原理介绍。

半僧的大数据杂谈 1006

数据结构(c语言)任务调度 实验报

数据结构试验报告 附代码 可运行 运用链表实现

scratch lenet(4): 开根号的C语言实现

使用C语言,分别使用二分法、牛顿法、卡马克快速法,求解正实数的开根号。包括公式推导、代码实现、运行结果,不使用任何第三方库和C标准库的数学库。

baiyu33的博客 4970

常见算法题分类总结之线程池与任务队列(Task-Queue)

这里首先放几个承接上个博客的链表题目,大家可以借此复习一下上一次所学内容,可以看看自己看题目之后是不是有思路了,可以先去力扣手动实现一下。 //分隔链表 public class Num86 { public ListNode partition(ListNode head, int x) { ListNode small = new ListNode(-1, head); ListNode big = new ListNode(-1, head); L

qq_57469718的博客 1157

Couldn‘t find device with uuid 恢复LVM元数据 linux

Couldn't find device with uuid 恢复LVM元数据 linux欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使

m0_57559579的博客 7171

[数据结构]Typescript实现队列

[数据结构]Typescript实现队列以及队列的功能

samroom的博客 1180

Amesim与Simulink联合仿真:S-Function接口配置与实战避坑指南

本文详细介绍了Amesim与Simulink联合仿真中S-Function接口的配置方法与实战避坑指南。从环境搭建、编译器配置到S-Function接口实战,逐步解析关键步骤与常见问题解决方案,帮助工程师高效实现多领域系统仿真,特别适合汽车、航空航天等复杂系统建模场景。

weixin_29173777的博客 344

全志DRM框架下LVDS双屏异显配置实战

本文详细介绍了在全志DRM框架下配置LVDS双屏异显的实战经验。涵盖硬件连接、内核配置、设备树修改、背光控制及U-Boot适配等关键步骤,重点解析屏参转换技巧与双屏route配置,帮助开发者解决工业控制台等多屏应用中的显示适配问题,提升开发效率。

rnn9storyteller的博客 814

TS:栈、队列

栈 LIFO:后进先出 class Stack { constructor(){ this.items = [] } // 从栈顶放入元素 push(...element){ this.items.push(...element) } // 从栈顶取出元素 pop(){ return this.items.pop() } size(){ return this.items.length } clear(){ this.items = []; } // 返回栈顶第

大空翼 つばさ 833

20231126-超详细Isaac Gym安装教程(基于双系统版本)

我一开始使用了WSL2虚拟环境试了集群服务器里面的交互式桌面,但是都失败了,WSL2因为没办法调用系统的GPU,应该有办法配置但我放弃了,感兴趣的可以自己探索(图片贴出来了)。服务器上出现的问题是Segmentation fault (core dumped),目前还没解决,有可能是驱动和cuda版本的问题(后面有时间再解决)等上图右边都达到了100%,就创建了一个名为rlgpu的conda环境,然后会出现success。注意安装版本要低于3.9!参考链接:非常详细,大家直接看这个博主的安装就行。

m0_37802038的博客 2万+

数据结构-使用ts创建一个队列

队列遵循先进先出

poppy995的博客 1012

基于STM32设计的心率脉搏测量仪(项目资料ID:9)

本设计基于STM32F103单片机开发了一款便携式心率脉搏测量仪,通过光电传感器采集脉搏信号,经放大(约1200倍)、滤波(低通及四阶低通滤波)、比较及偏置电压调理后,由STM32进行ADC采样与数据处理。硬件采用Altium Designer设计,包含信号调理电路(限定心率范围43.4-800次/分钟)及电源管理模块;软件基于STM32CubeMX开发,利用队列存储和时间间隔平均算法优化精度,实现多终端显示(OLED实时心率/动画、MATLAB波形分析、蓝牙传输至手机)。系统支持自动启停(检测脉搏启

以培养嵌入式工程师为己任 1万+

GPU硬件架构与微架构深度解析09-GPU寄存器文件深度解析

本文探讨GPU架构中大规模寄存器堆的设计与高效分配算法。寄存器文件作为GPU关键组件,支持大规模线程并行和快速数据存取。文章分析了多体寄存器堆的设计考量,包括端口数量、冲突避免和功耗管理,并比较了线性扫描、图着色等寄存器分配算法的特点。还介绍了寄存器压缩、动态分区等高级优化技术,以及NVIDIA Ampere架构的实际案例。这些技术对提升GPU计算性能和能效至关重要。

2301_79143213的博客 121

结构与算法7-34 任务调度的合理性 (dfs)

7-34任务调度的合理性(25分) 假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行。“任务调度”包括一组子任务、以及每个子任务可以执行所依赖的子任务集。 比如完成一个专业的所有课程学习和毕业设计可以看成一个本科生要完成的一项工程,各门课程可以看成是子任务。有些课程可以同时开设,比如英语和C程序设计,它们没有必须先修哪门的约束;有些课...

ItaLink 655

传导案例:某医疗仪器传导骚扰整改案例

紫外线光疗仪是一种专业的医疗设备,主要用于治疗银屑病、白癜风等皮肤疾病。该设备采用物理治疗技术,通过特定波长的紫外线照射人体来达到治疗效果。自1984年窄谱中波紫外线(NB-UVB)应用于临床以来,该技术已成为治疗早期蕈样肉芽肿(MF)的有效方法之一。作为二类医疗器械,紫外线光疗仪必须符合严格的电磁兼容性(EMC)标准,这不仅关系到设备自身的稳定运行,更关乎患者的使用安全和治疗效果。紫外线光疗仪传导骚扰整改案例充分展示了系统性EMC设计的重要性。

m0_56451176的博客 340

【数据结构练习】系统任务调度问题

// OSTaskScheme.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include using namespace std; #define Max 100 /*问题说明: 操作系统任务分为系统任务和用户任务两种。 系统任务的优先级 = 50且 <= 255。优先级大于255的为非法任务,应予以剔除。 现有一任务队列task[],长

人家 1952

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

任务调度方法和数据结构

数据结构 主机信息 任务请求方和任务响应方数据结构相同 #mermaid-svg-7Dq5Ua2kJA8iLkUW .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-7Dq5Ua2kJA8iLkUW .label text{fill:#333}#mermaid-svg-7Dq5Ua2kJA8iLkUW .node

cc0609的博客 345

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

TypeScript 实现任务队列

业务中经常会有一些批量操作的任务,比如使用 JavaScript 预加载一组图片,批量上传一些资源。如果这些任务一次性启动,势必会消耗很多资源和带宽。理想的做法应该对这些任务进行限制,比如一次只跑几个,当其中一些任务完成后,再添加新的任务到队列。 总的来说,我们需要这样一个服务,它提供一个添加任务的方法,内部将添加的方法维护在一个数组。然后根据...

weixin_30376323的博客 1484

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

typescript中的队列

队列类 class Queue { private data = []; push = item => this.data.push(item); pop = () => this.data.shift(); } typescript版本的队列 /** * pop的返回值当data为空时返回undefined * 使用了泛型约束 */ class QueueT<T>...

alias 3404

C# 批量任务队列

在实际项目中,需要批量处理一定数量的队列数据,而不是,一个一个处理,来提高效率。 但是,默认是不支持的。这个时候,就需要这样的一个业务逻辑对象。 /// <summary> /// 任务队列接口 /// </summary> public interface ITaskQueue<T> { /// &...

蓝创精英团队 2038

数据结构算法——1102. 任务调度问题

题目 思路 拓扑排序问题 用队列进行储存 把入度为0的点先存进去 然后利用vector来储存每个点对应的后置课程(出度 并用一个数组记录每个课程的前置课程数量 在出栈的时候把该前置课程对应的后置课程数组储存的数字-1(也就是入度-1) 在这个过程中数组储存的数变成0的话,入栈,如此往复 代码 #include<iostream> #include<vector> #include<queue> using namespace std; vector<int&gt

JamSlade的博客 1903

LTS 轻量级分布式任务调度框架(Light Task Scheduler)

框架概况:LTS是一个轻量级分布式任务调度框架。有三种角色, JobClient, JobTracker, TaskTracker。各个节点都是无状态的,可以部署多个,来实现负载均衡,实现更大的负载量, 并且框架具有很好的容错能力。 采用多种注册中心(Zookeeper,redis等)进行节点信息暴露,master选举。(Mongo or Mysql)存储任务队列和任务执行日志, netty做底层通

zhao9tian的专栏 8143
上一篇: 数据结构与算法之队列: LeetCode 622. 设计循环队列 (Ts, Py, Go版)
下一篇: Vue3源码梳理:computed计算属性的核心实现
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值