leetcode之621任务调度器Golang
题目描述
给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。
然而,两个相同种类的任务之间必须有长度为 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
你需要计算完成所有任务所需要的最短时间。
示例 :
输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B.
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
提示:
- 任务的总个数为
[1, 10000]。 n的取值范围为[0, 100]。
算法
我要哭啦,感觉自己是个笨B。。。。
其实很简单,CPU每一轮处理一系列任务,任务的个数就是冷却时间,并且每次处理的任务必须是当前个数最多的任务。
所以对任务进行排序,每次取出数量最多的前n+1个任务,然后将这些任务的数量减1,然后再重新排序
循环上述过程,直到整个任务队列为空
需要注意的地方就是任务队列的构建:
- 任务队列的长度为
max(n+1,任务的种类),也就是说选取的长度是冷却时间和任务的种类中的较大值
代码
type task struct {
kind byte
num int
}
type sortTasks []task
func (s sortTasks) Len() int {
return len(s)
}
func (s sortTasks) Less(i, j int) bool {
return s[i].num >= s[j].num
}
func (s sortTasks) Swap(i, j int) {
s[i].kind, s[i].num, s[j].kind, s[j].num = s[j].kind, s[j].num, s[i].kind, s[i].num
}
func leastInterval(tasks []byte, n int) int {
if len(tasks) == 0 {
return 0
}
time := 0
taskNum := make(map[byte]int)
for _, t := range tasks {
taskNum[t]++
}
taskQue := make([]task, len(taskNum))
init := 0
for t, num := range taskNum {
taskQue[init] = task{t, num}
init++
}
if len(taskQue) < n+1 {
tmp := make([]task, n+1-len(taskQue))
//当n+1比任务种类更多,任务队列后面就用0补齐
for i := 0; i < len(tmp); i++ {
tmp[i] = task{}
}
taskQue = append(taskQue, tmp...)
}
sort.Sort(sortTasks(taskQue))
for {
zeroIndex := 0
//记录最后一次归零的任务是在CPU的第几个时间处理的
for i := 0; i < n+1; i++ {
time++
if taskQue[i].num > 0 {
zeroIndex = i
taskQue[i].num--
}
}
sort.Sort(sortTasks(taskQue))
if taskQue[0].num == 0 {
time -= (n - zeroIndex)
break
}
}
return time
}
浙公网安备 33010602011771号