题目:
给你一个二维数组 tasks ,用于表示 n 项从 0 到 n - 1 编号的任务。其中 tasks[i] = [enqueueTimei, processingTimei] 意味着第 i 项任务将会于 enqueueTimei 时进入任务队列,需要 processingTimei 的时长完成执行。
现有一个单线程 CPU ,同一时间只能执行 最多一项 任务,该 CPU 将会按照下述方式运行:
- 如果 CPU 空闲,且任务队列中没有需要执行的任务,则 CPU 保持空闲状态。
- 如果 CPU 空闲,但任务队列中有需要执行的任务,则 CPU 将会选择 执行时间最短 的任务开始执行。如果多个任务具有同样的最短执行时间,则选择下标最小的任务开始执行。
- 一旦某项任务开始执行,CPU 在 执行完整个任务 前都不会停止。
- CPU 可以在完成一项任务后,立即开始执行一项新任务。
返回 **CPU **处理任务的顺序。
算法:
方法一:模拟
func getOrder(tasks [][]int) []int {
// 队列需要新增,删除,取processingTimes最短的任务,用堆
// 任务按进入调度队列时间排序
for i := range tasks {
tasks[i] = append(tasks[i], i)
}
sort.Slice(tasks, func(i, j int) bool {return tasks[i][0] < tasks[j][0]})
taskQueue := heapByProcessTime{}
curTime := 0
ans := make([]int, 0)
index := 0
for index < len(tasks) || len(taskQueue) != 0 {
// 将enqueueTime小于等于cur的task加入队列
for index < len(tasks) && tasks[index][0] <= curTime {
heap.Push(&taskQueue, pair{tasks[index][2], tasks[index][1]})
index ++
}
// 从队列中取出一个任务,将id加入结果,更新任务结束时间cur
if len(taskQueue) != 0 {
task := heap.Pop(&taskQueue).(pair)
ans = append(ans, task.i)
curTime = curTime + task.t
} else {
// 队列空闲了,时间跳转到下一个任务入队列时间
curTime = tasks[index][0]
}
}
return ans
}
// 保存task id和processingTime
type pair struct{i int; t int}
type heapByProcessTime []pair
func (h heapByProcessTime) Less(i, j int) bool {
if h[i].t == h[j].t {
return h[i].i < h[j].i
}
return h[i].t < h[j].t
}
func (h heapByProcessTime) Swap(i, j int) {h[i], h[j] = h[j], h[i]}
func (h heapByProcessTime) Len() int {return len(h)}
func (h *heapByProcessTime) Push(x interface{}) {
*h = append(*h, x.(pair))
}
func (h *heapByProcessTime) Pop() interface{} {
old := *h
n := len(old)
x := old[n - 1]
*h = old[:n - 1]
return x
}