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

news2024/9/20 22:54:42

一、题目

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还在,就选取deadline
            if (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还在,就选取deadline
            if (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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2073163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

硬件面试经典 100 题(81~90)题

81、请问下图电路中二极管 D1、D2 有什么作用&#xff1f; 在 Vi 输入电压接近于零时&#xff0c;D1、D2 给三极管 T1、T2 提供偏置电压&#xff0c;使 T1、T2 维持导通&#xff0c;以消除交越失真。 陈氏解释 这道题参见&#xff1a;硬件面试经典 100 题&#xff08;51~70 题…

【学习笔记】STM32F407探索者HAL库开发(三)IO分配

【学习笔记】STM32F407探索者HAL库开发&#xff08;三&#xff09;IO分配 1 STM32F407 IO资源分配表2 STM32F407ZGT6 引脚定义3 IO分配的重要性3.1 硬件设计优化3.2 软件编程3.3 系统性能提升 4 F1/F7/H7芯片的IO分配差异4.1 引脚数量和分组4.2 功能模式4.2.1 输入模式4.2.2 输…

Kubernetes 外部 etcd 集群的快速 Docker Compose 部署指南

一、背景 在高可用 Kubernetes 部署中&#xff0c;需要单独部署外部 etcd 集群&#xff0c;而不是使用 kubeadm 默认在 master 节点上部署的 etcd。以下是关于这一配置场景的详细记录。 二、etcd简介 etcd 是一个高可用的分布式键值存储系统&#xff0c;主要用于存储和管理配…

使用Qt+Visual Stuidio写一个简单的音乐播放器(1)

1.使用QMediaPlayer播放音乐 第三步:在代码头部加上: #include <QtMultimedia/QMediaPlayer> // VS向.pro文件添加代码的方式 #pragma execution_character_set("utf-8") // qt支持显示中文 QMediaPlayer类是一个高级媒体播放类。它可以用来播放歌曲、电…

leetcode 893. Groups of Special-Equivalent Strings

原题链接 You are given an array of strings of the same length words. In one move, you can swap any two even indexed characters or any two odd indexed characters of a string words[i]. Two strings words[i] and words[j] are special-equivalent if after any …

力扣: 设计链表

文章目录 需求代码结尾 需求 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 p…

Java 的数组详解

数组的定义 数组是相同类型数据的有序集合 数组描述的是相同类型的若干个数据&#xff0c;按照一定的先后次序排列组合而成 其中&#xff0c;每一个数据称作一个数组元素&#xff0c;每个数组元素可以通过一个下标(编号、标记)来访问它&#xff0c;下标是从 0 开始的&#xf…

100套动画PPT模版分享

100套动画PPT模板 目录下载链接 目录 下载链接 「动画模板」链接&#xff1a;https://pan.quark.cn/s/73ea2523f198 点击下载

中小型企业如何管理文档?8款工具来帮你

文章介绍了以下几个工具&#xff1a;PingCode、Worktile、氚云、泛微、中通天鸿、Tower、知因智慧、SharePoint。 在中小型互联网企业中&#xff0c;文档知识库的管理常常让人头疼。团队成员散布在不同的地点&#xff0c;文档分散在各种工具中&#xff0c;查找信息变得异常困难…

Linux启动流程和Systemd特性

文章目录 内核设计流派linux启动流程1.硬件加电自检2.启动加载器bootloader3.加载kernel4.init初始化5.用户终端启动 systemdsystemd特性systemd的unitunit配置文件 systemctl管理系统服务service unit服务状态 service unit文件格式Unit段Service段Install段 内核设计流派 1.…

资源第二篇:bundle 的config.json 文件内容的解析

简介 本篇文章主要是对bundle包的核心文件config.json 的分析。config.json记录着整个bundle包的具体信息&#xff0c;并通过config.json 去解析整个bundle包。 bundle 目录下的文件结构 import 存放所有的json。场景、预制体、texture2D配置等jsonnative 存放所有的实际资源…

分子属性梯度引导的3D分子生成扩散模型 TAGMOL - 评测

TAGMoL 是一个基于分子属性条件引导扩散的 3D 分子生成模型&#xff0c;适合在给定靶标蛋白质的情况下&#xff0c;可以生成一系列满足目标特性&#xff08;分子属性&#xff0c;binding affinity&#xff09;的候选分子。 一、背景介绍 TAGMoL 来源于新德里 Molecule AI, 以及…

ESP32 出现 failed to load RF 报错

前言 个人邮箱&#xff1a;zhangyixu02gmail.com 正文 周五我测试程序没有问题&#xff0c;板子放在桌子上就没动过了。周一过来的时候&#xff0c;重新烧录程序&#xff0c;就发现出现如下报错。最终发现是电池过放导致电池损坏功率不够&#xff0c;因此 RF 无法启动&#…

探寻少儿自闭症的解决之道

自闭症&#xff0c;又称孤独症谱系障碍&#xff0c;是一种广泛性发育障碍&#xff0c;给无数家庭带来了沉重的负担。然而&#xff0c;随着科学技术的不断进步和人们对自闭症认识的逐步深入&#xff0c;越来越多的方法和途径正在被探索出来&#xff0c;为自闭症的解决带来了希望…

RocketMQ 与 Spring Cloud Stream之事务消息配置

1 引言 RocketMQ的事务消息设计是为了解决分布式系统中数据一致性的问题。在分布式系统中&#xff0c;由于数据可能分布在不同的服务或节点上&#xff0c;因此需要一种机制来确保数据的最终一致性。事务消息通过引入本地事务和消息状态的关联&#xff0c;确保了消息的发送与本…

【什么是“Binary“二进制文件?】

“Binary”二进制文件是计算机文件的一种形式。部件文件是开发人员编写的源代码文件&#xff0c;还未被编译成可执行的机器代码&#xff0c;通常具有如.c、.cpp、.java 等扩展名。对象文件是部件文件经过编译器编译生成的中间文件&#xff0c;包含了部件文件的机器代码和符号表…

链表OJ题——环形链表2

文章目录 一、题目链接二、解题思路三、解题代码 一、题目链接 环形链表2 题目描述&#xff1a;在链表有环的基础上&#xff0c;找出环的入口点。 二、解题思路 三、解题代码

移动端爬虫学习记录

免责声明 本文旨在探讨移动端爬虫技术的应用和挑战&#xff0c;仅供教育和研究用途。请确保在合法合规的框架内使用爬虫技术&#xff0c;遵循相关法律法规和网站的使用条款。作者不对因使用本文内容而产生的任何法律或安全问题承担责任。 1、初识移动端爬虫 学习移动端爬虫的原…

.NET 开发的高性能内网穿透工具

目录 前言 什么是NSmartProxy&#xff1f; 项目特点 运行原理 客户端安装 服务端安装 使用案例 项目地址 最后 前言 在许多情况下&#xff0c;我们需要从外部网络访问内部网络中的服务&#xff0c;比如家里的服务器或者公司的内部资源。这时内网穿透工具就可以帮助我们…

【吊打面试官系列-Memcached面试题】什么是二进制协议,我该关注吗?

大家好&#xff0c;我是锋哥。今天分享关于 【什么是二进制协议&#xff0c;我该关注吗&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是二进制协议&#xff0c;我该关注吗&#xff1f; 关于二进制最好的信息当然是二进制协议规范&#xff1a; 1000道 互…