「 【华为OD机试真题 Go语言实现】468、可以处理的最大任务数、任务处理 | 机试真题+思路参考+代码解析(C卷)(本题100%)」2024年7月11日

一、题目


🎃题目描述

在某个项目中有多个任务(用 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 1

2 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
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值