Leetcode:Task Scheduler分析和实现
题目大意:提供k个任务,这些任务没有依赖关系(即可以任意调度)。CPU完成一个任务需要耗时一个时间片段,当执行完一个任务后,相同的任务必须在n个时间片段才能得以执行。请问CPU通过调度最快能在多少时间片段内完成所有任务。
有难度的一道题目。我借鉴了https://discuss.leetcode.com/topic/92852/concise-java-solution-o-n-time-o-26-space的思路。下面按照我个人理解进行说明:
首先我们将任务进行分组,相同的任务分入一组。对于T类任务,我们记N(T)为任务T所在分组包含的任务数,读作T的提交数。这里记m为所有类型任务中最大提交数,s为提交数为m的任务类型的总数目。
最终结果r显然不可能小于任务总数k,并且也肯定不会小于(m-1)*(n+1)+s。这里稍微说明下这个公式的含义。首先我们取任意一个提交数为最大提交数的任务类型T,令其在第一个时间片段中执行第一次,那么显然最后一次必定是在(m-1)*(n+1)时间片段之后执行的,当其在(m-1)*(n+1)+1时间片段执行了最后一次,那么T类型任务占用的时间片必定为1,n+2,2n+3,...,(m-1)*(n+1)+1,其是紧密排列的。而对应的要完成所有提交数为m的s个任务类型,我们最少也需要(m-1)*(n+1)+s个时间片段。
因此如果我们能找到一个有效的调度方式使得CPU能在max(k, (m-1)*(n+1)+s)的时间片段内完成所有任务,那么这个调度方式必定是最优的(因为不可能存在更快的调度方式)。接下来说明如何利用这些时间片段完成所有任务。
接下来描述一个构造性的算法:首先我们对将被执行的任务分隔为m个分块,用序号0,...,m-1来标志。每个任务块的前s个任务均为提交数为m的任务。对于其余未被调度的任务,我们将其按照任务种类进行排序(保证同类任务连续被调度),之后遍历所有剩余未被调度的任务,对于第i个任务,我们将其分配在第i%(m-1)的任务分块中,并追加到该任务分块中的后续第一个时间片段中。接着对于所有包含少于n+1个任务的任务块,我们在尾部追加空事件(IDLE),直到其长度刚好达到n+1。最后将这些分块按编号顺序连接起来,得到的就是整个调度序列。
我们先说明这个调度算法得到的调度序列是有效的,即每个同种类任务的执行的时间片段都最少相隔n。显然对于提交数为m的任务,是满足这个约束的,接下来只需要考虑所有提交数少于m的任务。假设两个F类任务违反了约束,其必定是被调度到了同一任务块中,假设二者在排序序列中的下标为i和j,由i%(m-1)=j%(m-1)可知i-j=z(m-1),而i不等于j,故|i-j|>=m-1,即F种类的任务提交数最少有m个,这与前提相悖,故所有提交数少于m的任务都是不冲突的。
再说明调度算法所导出的结果的长度为max(k, (m-1)*(n+1)+s)。考虑两种情况,一种是任务块长度不足需要我们补充IDLE,这时候的总共花费的时间片段为(m-1)*(n+1)+s。另外一种就是任务块长度足够甚至超出,此时由于没有添加IDLE,整个导出的序列都是由有效任务组成的,此时导出序列的长度为k。这两种情况下导出序列的上界均为max(k, (m-1)*(n+1)+s),而前面也已经说明过了max(k, (m-1)*(n+1)+s)是最终结果的下界,故最终结果必然为max(k, (m-1)*(n+1)+s)。
由于我们并真正对任务进行调度,而只是求max(k, (m-1)*(n+1)+s),其中求s和m的时间复杂度为O(n),故总的时间复杂度为O(n),而要保存每个任务类型的提交数,需要O(26)的空间复杂度。
最后提供代码:
class Solution {
public int leastInterval(char[] tasks, int n) {
int[] counter = new int[26];
int taskNum = tasks.length;
for(int i = 0; i < taskNum; i++)
{
counter[tasks[i] - 'A']++;
}
int max = 0;
int same = 0;
for(int i = 0; i < 26; i++)
{
if(counter[i] > max)
{
max = counter[i];
same = 1;
}
else if(counter[i] == max)
{
same++;
}
}
return Math.max((max - 1) * (n + 1) + same, taskNum);
}
}
Leetcode:Task Scheduler分析和实现的更多相关文章
- [LeetCode] Task Scheduler 任务行程表
Given a char array representing tasks CPU need to do. It contains capital letters A to Z where diffe ...
- Windows Task Scheduler Fails With Error Code 2147943785
Problem: Windows Task Scheduler Fails With Error Code 2147943785 Solution: This is usually due to a ...
- 在Windows Server 2012的Task Scheduler里面配置自动发送邮件
最近在一台server上配置了每个周末备份数据库的定时任务,想顺手配置发送备份完成的邮件提醒我去Double Check一下备份结果. 悲剧地发现Send an email功能被新版的server给禁 ...
- Task Scheduler Error and Success Constants (Windows)
If an error occurs, the Task Scheduler APIs can return one of the following error codes as an HRESUL ...
- 使用C#创建计划任务(How to create a Task Scheduler use C# )
本文主要讲解了如何使用C#来创建windows计划任务. 需求:在不定时间段运行多个后台程序(winfrom,wpf,console,等等)用于更新数据. 问题:为什么要使用计划任务,而不直接在程序 ...
- SpringBoot2 task scheduler 定时任务调度器四种方式
github:https://github.com/chenyingjun/springboot2-task 使用@EnableScheduling方式 @Component @Configurabl ...
- Task Scheduler
https://technet.microsoft.com/en-us/library/cc748993(v=ws.11).aspx#BKMK_winui If Task Scheduler is n ...
- Spring的任务调度@Scheduled注解——task:scheduler和task:executor的解析
原文地址: https://blog.csdn.net/yx0628/article/details/80873774 一个简单的Spring定时任务的 demo,全部代码见下载地址:https:// ...
- Task Scheduler API Error 80041318
https://stackoverflow.com/questions/42307917/task-scheduler-api-error-80041318/42462235#42462235 Hi ...
随机推荐
- Python中实现装饰模式的三种方式
功能目标 编写一个可以打印被装饰函数名称.执行时间.内存地址得装饰器 前置依赖包 import time import functools from decorator import decorato ...
- 基于Photon 的 PUN+ 如何自动实现RPC呼叫的.
基于Photon 的 PUN+ 如何自动实现RPC呼叫的. 简单说函数标记成 RPC 类型的. void Hello() { Debug.Log("Hello"); PhotonV ...
- 后台导入导出Excel
Excel导出 定义数据模型 参考财付通的批量提现Excel的格式,定义模型如下 private int recordId; //提现id private String cname; //提现人名称 ...
- iOS AnchorPoint 引起的坐标问题
这里主要讨论设置AnchorPoint 改变时,会影响我们预期的布局问题: 一.初始代码布局 //参照页面 UIView *aView = [[UIView alloc]initWit ...
- 监听Documents文件夹内文件发生改变
// 当Documents内文件发生改变时,启动计时器,每秒计算一次大小,当大小不发生改变时说明传输完毕,就开始刷新. @property (nonatomic, strong) NSTimer *t ...
- LeetCode Minimum Time Difference
原题链接在这里:https://leetcode.com/problems/minimum-time-difference/description/ 题目: Given a list of 24-ho ...
- 【java规则引擎】基本语法和相关属性介绍
一个规则的语法信息 [1]条件部分(LSH部分)===>规则pattern之间的连接条件符号: (1)LHS 部分是由一个或多个条件组成,条件又称之为 pattern(匹配模式),多个 pa ...
- redis key设计技巧
把表名转换为key前缀, 第二端放置表用于区分区key的字段–对应mysql中的主键的列名如userid. 3.放置主键值,如1,2,3,…..,a,b,c. 4.放要存储的列名 user表 user ...
- Oracle变量的定义、赋值及使用
首先我们来看看代码,然后我们在说明和解释代码: declare l_dept ; currtime date := sysdate; l_nam ) :),'yyyymmdd'); -- to_cha ...
- Redis 字符串(String)
Redis 字符串(String) Redis 字符串数据类型的相关命令用于管理 redis 字符串值,基本语法如下: 语法 redis 127.0.0.1:6379> COMMAND KEY_ ...