一、题目
🎃题目描述
在某个项目中有多个任务(用 tasks 数组表示)需要您进行处理,其中 tasks[i] = [si,ei],你可以在 si <= day <= ei 中的任意一天处理该任务; 请返回你可以处理的最大任务数 注:一天可以完成一个任务的处理
🎃输入输出
输入 第一行为任务数量n,1 <= n = 100000,后面n行表示各个任务的开始时间和终止时间,用 si 和ei 表示,1<= si= ei<=100000 输出 输出为一个整数,表示可以处理的最大任务数
🎃样例1
输入 4 1 1 1 2 1 3 2 2 输出 3 说明: 第一天处理任务1,第二天处理任务2,第三天处理任务3
🎃样例2
输入
3
1 1
1 1
1 1
输出
1
🎃样例3
输入
4
1 1
1 1
1 12 5
输出
2
二、思路参考
解题思路 对于每一天安排; 第一步,找到可以开始的任务,加入工作队列; 第二步,给该天安排一个任务 重复上述步骤,直到处理完所有的任务 这个题目的特点在于,任务本身可能时间冲突,而不限制可以使用的天数。
三、实现参考
type item struct {
si int
ei int
}
type Q []*item
func (q Q) Len() int {
return len(q)
}
func (q Q) Swap(i, j int) {
q[i], q[j] = q[j], q[i]
}
type BySi struct {
Q
}
func (b BySi) Less(i, j int) bool {
return b.Q[i].si < b.Q[j].si
}
func maxTasks(tasks []*item) int {
// 按照任务开始时间排序
sort.Sort(BySi{tasks})
// 初始化一个队列用于记录任务的结束时间
var queue []int
taskIdx := 0
maxTask := 0
// 这里的天数其实可以到最大的ei
for day := 1; day <= maxEI(tasks); day++ {
// taskIdx(包括)之后的任务,且开始时间<=当天的任务加入待完成队列
for i := taskIdx; i < len(tasks); i++ {
if tasks[i].si <= day {
queue = append(queue, tasks[i].ei)
taskIdx++
}
}
// 根据结束时间从早到晚排序
sort.Ints(queue)
// 安排当天的任务
// 把过期的任务 t.ei < day 的任务删除
for len(queue) > 0 && queue[0] < day {
queue = queue[1:]
}
if len(queue) > 0 && queue[0] >= day { // 如果队列不空,而且队首任务的结束时间>=当前日期(day)
maxTask++
queue = queue[1:]
}
}
return maxTask
}
func maxEI(t []*item) int {
maxDay := 0
for _, i := range t {
if i.ei > maxDay {
maxDay = i.ei
}
}
return maxDay
}
func solution468() {
// 任务数量
var n int
fmt.Scanf("%d", &n)
tasks := make([]*item, n)
for i := 0; i < n; i++ {
tasks[i] = &item{}
fmt.Scanf("%d %d", &tasks[i].si, &tasks[i].ei)
}
}
func Test468(t *testing.T) {
t.Log(maxTasks([]*item{{1, 1}, {1, 2}, {1, 3}}))
// output: 3
t.Log(maxTasks([]*item{{1, 1}, {1, 1}, {1, 1}, {2, 5}}))
// output: 2
}
1149

被折叠的 条评论
为什么被折叠?



