华为OD机试 - 任务处理 - 贪心算法(Java 2024 D卷 100分)

在这里插入图片描述

华为OD机试 2024D卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

在某个项目中有多个任务(用 tasks 数组表示)需要您进行处理,其中 tasks[i] = [si, ei],你可以在 si <= day <= ei 中的任意一天处理该任务。请返回你可以处理的最大任务数。

注:一天可以完成一个任务的处理。

二、输入描述

第一行为任务数量 n,1 <= n <= 100000。后面 n 行表示各个任务的开始时间和终止时间,用 si 和 ei 表示,1 <= si <= ei <= 100000。

三、输出描述

输出为一个整数,表示可以处理的最大任务数。

四、测试用例

1、输入

3
1 1
1 2
1 3

2、输出

3

3、说明

每个任务都可以在其唯一的一天完成:

第一个任务在第1天完成。
第二个任务在第2天完成。
第三个任务在第3天完成。

五、解题思路

1、贪心算法

为了找到可以处理的最大任务数,我们可以使用贪心算法来解决这个问题。

采用贪心算法解决这道题的原因是因为我们需要在给定的时间范围内选择尽可能多的任务,而贪心算法通过每一步选择当前局部最优解(即选择结束时间最早的任务),能够确保全局最优解(即最大化可以处理的任务数量)。

2、核心思想:

  1. 任务排序:首先将所有任务按照结束时间 ei 进行排序。因为在贪心算法中,我们优先选择结束时间最早的任务,这样可以留下更多的时间来处理后续任务。
  2. 任务选择:从排序后的任务列表中,依次选择可以处理的任务。如果一个任务的开始时间 si 大于等于当前处理任务的结束时间 currentEndDay,则选择这个任务,并更新 currentEndDay 为该任务的结束时间加一天。

3、具体步骤

  1. 读取输入:读取任务数量 n 和每个任务的开始时间 si 和结束时间 ei。
  2. 排序任务:按照任务的结束时间 ei 进行排序。
  3. 遍历任务列表:遍历排序后的任务列表,选择可以处理的任务,并记录可以处理的任务数量。
  4. 输出结果:输出可以处理的最大任务数。

六、Java算法源码

public class OdTest02 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 读取任务数量
        int taskCount = scanner.nextInt();

        // 读取任务的开始时间和结束时间
        int[][] tasks = new int[taskCount][2];
        for (int i = 0; i < taskCount; i++) {
            tasks[i][0] = scanner.nextInt();
            tasks[i][1] = scanner.nextInt();
        }

        // 将所有任务按照结束时间降序排序
        Arrays.sort(tasks, (task1, task2) -> task2[1] - task1[1]);

        // 优先队列中记录的是任务的开始时间,并且开始时间越大,优先级越高
        PriorityQueue<Integer> startTimeQueue = new PriorityQueue<>((start1, start2) -> start2 - start1);

        // 记录当前处理的任务的结束时间
        int currentEndTime = Integer.MAX_VALUE;

        // 最大任务数
        int maxTaskCount = 0;

        for (int[] task : tasks) {
            // 当前任务的开始和结束时间
            int start = task[0];
            int end = task[1];

            // 如果当前任务的结束时间小于优先队列中记录的任务的结束时间,
            // 则两个结束时间之间的间隔时间段,可以处理一些紧急任务
            while (startTimeQueue.size() > 0 && end < currentEndTime) {
                // 处理时间短的任务,即开始时间比较大的任务
                if (startTimeQueue.poll() <= currentEndTime) {
                    // 如果紧急任务的开始时间未超过其结束时间,则可以执行
                    maxTaskCount++;
                    currentEndTime--; // 一个时刻只执行一个任务
                }
            }

            // 间隔时间消耗完后,优先队列中的任务的结束时间全部更新为当前任务的结束时间
            startTimeQueue.add(start);
            currentEndTime = end;
        }

        // 收尾处理
        while (startTimeQueue.size() > 0) {
            if (startTimeQueue.poll() <= currentEndTime) {
                maxTaskCount++;
                currentEndTime--;
            }
        }

        System.out.println(maxTaskCount);
    }
}

七、效果展示

1、输入

5
1 2
2 3
3 4
4 5
5 6

2、输出

5

3、说明

每个任务可以在其唯一的区间内完成:

第一个任务在第1天完成。
第二个任务在第2天完成。
第三个任务在第3天完成。
第四个任务在第4天完成。
第五个任务在第5天完成。

在这里插入图片描述


🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 D卷 200分)

🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值