您的位置:首页 > 娱乐 > 明星 > 贪心处理任务(华为od机考题)

贪心处理任务(华为od机考题)

2025/2/24 9:24:42 来源:https://blog.csdn.net/qq_57223586/article/details/141525216  浏览:    关键词:贪心处理任务(华为od机考题)

一、题目

1.原题

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

2.题目理解

贪心算法‌:如果任务可以按照结束时间排序,并且后续任务的开始时间晚于或等于当前任务的结束时间,那么可以贪心地选择尽可能多的任务。

例如,平时购物找零钱时,为使找回的零钱的硬币数最少,不要求找零钱的所有方案,而是从最大面值的币种开始,按递减的顺序考虑各面额,先尽量用大面值的面额,当不足大面值时才去考虑下一个较小面值,这就是贪心算法 。

将任务按结束时间排序后:

eg:[1, 4][3, 5][2, 7][6, 9]

task[0]可选择时间有:{1,2,3,4};

task[1]可选择时间有:{3,4,5};

task[2]可选择时间有:{2,3,4,5,6,7};

task[3]可选择时间有:{6,7,8,9}。

完整时间片为:1-9:{1,2,3,4,5,6,7,8,9}

从结束时间最晚的task[3]开始抓取,

选取9后task[3]完成了;

再到了task[2]选取最大值7;

再到了task[1]选取最大值5;

再到了task[0]选取最大值4;

每次都选择最大的,确保前边的值选择空间更多!

二、思路与代码过程

1.思路

输入:

任务数量n

tasks[n]数组

输出:

可以处理的最大任务数

贪心算法

2.代码过程

①main函数

public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入该项目所含有的任务数量n:");int n = sc.nextInt();System.out.println("请输入任务数组tasks:");int [][] tasks = new int[n][2];for (int i = 0; i < n; i++) {tasks[i][0] = sc.nextInt();tasks[i][1] = sc.nextInt();}int maxTake = TaskCount(tasks) ;System.out.println("可以处理的最大任务数为:"+maxTake);}

②TaskCount

private static int TaskCount(int[][] tasks) {int canTake = 0 ;/*1.找到AllCanChose数组*/int min = Arrays.stream(tasks) // 将二维数组转换为流.flatMapToInt(Arrays::stream) // 展平为一维流.min() // 获取最小值.orElseThrow(() -> new IllegalArgumentException("Array is empty"));int max = Arrays.stream(tasks).flatMapToInt(Arrays::stream).max().orElseThrow(()->new IllegalArgumentException("Array is empty"));Set<Integer> AllCanChose = new HashSet<>();//固定值for (int i = min ;i<=max ;i++) {AllCanChose.add(i);}/*2.对任务数组排序*/int[][] sortedTasks = Arrays.stream(tasks).sorted(Comparator.comparing(a -> a[1])).toArray(int[][]::new);/*3.将一个个任务数组拆分为时间点和所有可选择天数数组一起传给TakeOrNot函数进行处理*/for (int i = sortedTasks.length-1; i >= 0; i--) {ArrayList<Integer> partCanTake = new ArrayList<>();//随i改变,每一次都是一组新的int start = sortedTasks[i][0];int end = sortedTasks[i][1];for (int j =start;j<=end;j++) {partCanTake.add(j);}boolean takeOrnot =  TakeOrNot(AllCanChose,partCanTake);if (takeOrnot){canTake++;}}return canTake;}

③TakeOrNot

/*判断当前任务是否可以接取,在哪一天接*/private static boolean TakeOrNot(Set<Integer> allCanChose, ArrayList<Integer> partCanTake) {boolean takeOrnot = false;if (allCanChose.size() !=0) {int deadline = partCanTake.get(partCanTake.size()-1);//如果在可选天里边当前任务的deadline还在,就选取deadlineif (allCanChose.contains(deadline)) {allCanChose.remove(deadline);takeOrnot = true;}//如果deadline已经被前边一个选走了:eg; 1,2 1,2 2,4 3,4//顺延到前一天,若前一天也被选取了,继续前一天,如果没有可以选的,该任务就做不了(递归)else {if (partCanTake.size()>1){partCanTake.remove(partCanTake.size()-1);takeOrnot = TakeOrNot(allCanChose, partCanTake);} else if (partCanTake.size()==1){return takeOrnot;}}}else {return takeOrnot;}return takeOrnot;}

三、运行结果

1.运行截图

2.带数据分析运行结果

tasks数组的最小值为:1
tasks数组的最大值为:4
所有可以选择的天有:[1, 2, 3, 4]
按照结束时间排序后的任务组为:
[1, 2]
[1, 2]
[2, 4]
[3, 4]

当前处理任务为:[3, 4]
当前任务可选择的天数有:[3, 4]
partCanTake的最后一天还可以选择!
选走最后一天后,剩余可选天数为:[1, 2, 3]

当前处理任务为:[2, 4]
当前任务可选择的天数有:[2, 3, 4]
移除最后一天后可选的有:[2, 3]
partCanTake的最后一天还可以选择!
选走最后一天后,剩余可选天数为:[1, 2]

当前处理任务为:[1, 2]
当前任务可选择的天数有:[1, 2]
partCanTake的最后一天还可以选择!
选走最后一天后,剩余可选天数为:[1]

当前处理任务为:[1, 2]
当前任务可选择的天数有:[1, 2]
移除最后一天后可选的有:[1]
partCanTake的最后一天还可以选择!
选走最后一天后,剩余可选天数为:[]

可以处理的最大任务数为:4

3.带数据分析完整代码

import javax.net.ssl.SSLContext;
import java.util.*;public class test34 {public static void main(String[] args) {/*Scanner sc = new Scanner(System.in);System.out.println("请输入该项目所含有的任务数量n:");int n = sc.nextInt();System.out.println("请输入任务数组tasks:");int [][] tasks = new int[n][2];for (int i = 0; i < n; i++) {tasks[i][0] = sc.nextInt();tasks[i][1] = sc.nextInt();}for (int[] task : tasks) {System.out.println(Arrays.toString(task));}*/int [][] tasks = {{1,2},{1,2},{2,4},{3,4}};int maxTake = TaskCount(tasks) ;System.out.println("可以处理的最大任务数为:"+maxTake);}private static int TaskCount(int[][] tasks) {int canTake = 0 ;/*1.找到AllCanChose数组*/int min = Arrays.stream(tasks) // 将二维数组转换为流.flatMapToInt(Arrays::stream) // 展平为一维流.min() // 获取最小值.orElseThrow(() -> new IllegalArgumentException("Array is empty"));int max = Arrays.stream(tasks).flatMapToInt(Arrays::stream).max().orElseThrow(()->new IllegalArgumentException("Array is empty"));System.out.println("tasks数组的最小值为:" +min);System.out.println("tasks数组的最大值为:" +max);Set<Integer> AllCanChose = new HashSet<>();//固定值for (int i = min ;i<=max ;i++) {AllCanChose.add(i);}System.out.println("所有可以选择的天有:"+AllCanChose);/*2.对任务数组排序*/int[][] sortedTasks = Arrays.stream(tasks).sorted(Comparator.comparing(a -> a[1])).toArray(int[][]::new);System.out.println("按照结束时间排序后的任务组为:");for (int[] task : sortedTasks) {System.out.println(Arrays.toString(task));}System.out.println();/*3.将一个个任务数组拆分为时间点和所有可选择天数数组一起传给TakeOrNot函数进行处理*/for (int i = sortedTasks.length-1; i >= 0; i--) {System.out.println("当前处理任务为:"+Arrays.toString(sortedTasks[i]));ArrayList<Integer> partCanTake = new ArrayList<>();//随i改变,每一次都是一组新的int start = sortedTasks[i][0];int end = sortedTasks[i][1];for (int j =start;j<=end;j++) {partCanTake.add(j);}System.out.println("当前任务可选择的天数有:"+partCanTake);boolean takeOrnot =  TakeOrNot(AllCanChose,partCanTake);//System.out.print("每一次的判断:"+takeOrnot);if (takeOrnot){canTake++;}}return canTake;}/*判断当前任务是否可以接取,在哪一天接*/private static boolean TakeOrNot(Set<Integer> allCanChose, ArrayList<Integer> partCanTake) {boolean takeOrnot = false;if (allCanChose.size() !=0) {int deadline = partCanTake.get(partCanTake.size()-1);//如果在可选天里边当前任务的deadline还在,就选取deadlineif (allCanChose.contains(deadline)) {System.out.println("partCanTake的最后一天还可以选择!");allCanChose.remove(deadline);System.out.println("选走最后一天后,剩余可选天数为:"+allCanChose);System.out.println();takeOrnot = true;}//如果deadline已经被前边一个选走了:eg; 1,2 1,2 2,4 3,4//顺延到前一天,若前一天也被选取了,继续前一天,如果没有可以选的,该任务就做不了(递归)else {if (partCanTake.size()>1){partCanTake.remove(partCanTake.size()-1);System.out.println("移除最后一天后可选的有:"+partCanTake);takeOrnot = TakeOrNot(allCanChose, partCanTake);} else if (partCanTake.size()==1){System.out.println("没有时间选啦,这个任务完成不了!");}}}else {System.out.println("可选时间已经没了,当前任务量就是最大的啦!");}return takeOrnot;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com