华为23年9月笔试原题,巨详细题解,附有LeetCode测试链接

请添加图片描述

文章目录

  • 前言
  • 思路
  • 主要思路
  • 关于f函数的剖析
  • Code
    • 就到这,铁子们下期见!!!!

前言

铁子们好啊!今天阿辉又给大家来更新新一道好题,下面链接是23年9月27的华为笔试原题,LeetCode上面的hard难题,阿辉带大伙来拿下它!!!
你可以安排的最多任务数目

思路

二分和单调队列以及一丢丢贪心

主要思路

  • 先按照任务难度和工人能力排序

  • 二分的范围是[l,r)左闭右开,l = 0,r = n+1,最多完成n个任务,n取任务数与工人数的较小值,因为左闭右开,所以rn+1,最少完成0个任务,所以l0

  • 然后就是如何判断lr的中点m是否是能够完成的任务数

    • 排序的重要就在这里体现了,我们取任务难度最小的m个与能力最强的m个工人如果能够完成,那就能完成,如果不能就完成不了

主逻辑代码:

// 主函数,用于找出可以分配的最大任务数量。
    int maxTaskAssign(vector<int>& tasks, vector<int>& workers, int pills, int strength) {
        int n = min(tasks.size(), workers.size()); // 取任务数和工人数中较小的一个,因为任务数不能超过工人数。
        int l = 0; // 二分查找的左边界
        int r = n+1; // 二分查找的右边界
        sort(tasks.begin(), tasks.end()); // 将任务按难度排序
        sort(workers.begin(), workers.end()); // 将工人按能力排序
        
        // 二分查找,确定最大可分配任务数
        while (l < r) {
            int m = l + (r - l) / 2; // 中间点
            //f函数用于判断是否可以完成m个任务
            if (f(tasks, workers, pills, strength, m)) {
                l = m + 1; // 如果能完成m个任务,则尝试增加任务数
            } else {
                r = m; // 如果不能完成m个任务,则减少任务数
            }
        }
        return l - 1; // 返回最终的任务数(因为在二分查找结束时,l指向的是第一个不能完成的任务数)
    }

关于f函数的剖析

f函数的空间复杂度是 O ( M ) O(M) O(M),因为ij都只前进不回退,也就是只遍历2m长度的数组
N为任务数组与工人数组的较大值
然后主函数排序两个数组是 O ( N l o g N ) O(NlogN) O(NlogN),二分加上f函数最多也不超过 O ( N l o g N ) O(NlogN) O(NlogN)
所以时间复杂度 O ( N l o g N ) O(NlogN) O(NlogN)
空间复杂度低于 O ( N ) O(N) O(N),队列长度取决于完成任务的数量

    int deque[50001]; // 一个双端队列,用于存储可能通过使用或不使用药丸完成的任务。
    // 辅助函数,用于判断是否能在当前条件下完成m个任务。
    bool f(vector<int>& ts, vector<int>& ws, int p, int s, int m) {
        int h = 0, t = 0; // 双端队列的头部和尾部指针
        //i指向最容易完成的第一个任务,j指向能力第m强的工人
        //遍历m个最容易完成的任务以及能力最强的m个工人
        for (int i = 0, j = ws.size() - m; j < ws.size(); ++j) {
            // 遍历每一个工人,并尝试分配任务
            while (i < m && ts[i] <= ws[j]) {
                // 如果当前任务可以由工人直接完成,则将其加入队列
                deque[t++] = ts[i++];
            }
            //经过上面的if如果队列里面没东西,说明该试试药了
            //如果队列里面有东西,可能是前一个工人嗑药留下的
            if (h == t || ws[j] < deque[h]) {
                // 如果队列为空,或当前工人无法完成队列头部的任务,则尝试使用药丸
                --p; // 使用一颗药丸
                while (i < m && ts[i] <= ws[j] + s) {
                    // 将可以通过使用药丸完成的任务加入队列
                    deque[t++] = ts[i++];
                }
                if (h == t || p < 0 || ws[j] + s < deque[h]) {
                    // 如果队列依然为空,或药丸用完,或即使使用药丸也无法完成队列头部的任务,则返回false
                    return false;
                }
                --t; // 上面没返回说明嗑药有用,完成最难的任务,一点子贪心各位肯定能懂,队列尾部指针前移
            } else {//否则
                ++h; // 工人直接完成了队列头部的任务,队列头部指针后移
            }
        }
        //能走到这就说明能完成
        return true; 

Code

class Solution {
public:
   
    // 主函数,用于找出可以分配的最大任务数量。
    int maxTaskAssign(vector<int>& tasks, vector<int>& workers, int pills, int strength) {
        int n = min(tasks.size(), workers.size()); // 取任务数和工人数中较小的一个,因为任务数不能超过工人数。
        int l = 0; // 二分查找的左边界
        int r = n+1; // 二分查找的右边界
        sort(tasks.begin(), tasks.end()); // 将任务按难度排序
        sort(workers.begin(), workers.end()); // 将工人按能力排序
        
        // 二分查找,确定最大可分配任务数
        while (l < r) {
            int m = l + (r - l) / 2; // 中间点
            if (f(tasks, workers, pills, strength, m)) {
                l = m + 1; // 如果能完成m个任务,则尝试增加任务数
            } else {
                r = m; // 如果不能完成m个任务,则减少任务数
            }
        }
        return l - 1; // 返回最终的任务数(因为在二分查找结束时,l指向的是第一个不能完成的任务数)
    }
    int deque[50001]; // 一个双端队列,用于存储可能通过使用或不使用药丸完成的任务。
    // 辅助函数,用于判断是否能在当前条件下完成m个任务。
    bool f(vector<int>& ts, vector<int>& ws, int p, int s, int m) {
        int h = 0, t = 0; // 双端队列的头部和尾部指针
        for (int i = 0, j = ws.size() - m; j < ws.size(); ++j) {
            // 遍历每一个工人,并尝试分配任务
            while (i < m && ts[i] <= ws[j]) {
                // 如果当前任务可以由工人直接完成,则将其加入队列
                deque[t++] = ts[i++];
            }
            if (h == t || ws[j] < deque[h]) {
                // 如果队列为空,或当前工人无法完成队列头部的任务,则尝试使用药丸
                --p; // 使用一颗药丸
                while (i < m && ts[i] <= ws[j] + s) {
                    // 将可以通过使用药丸完成的任务加入队列
                    deque[t++] = ts[i++];
                }
                if (h == t || p < 0 || ws[j] + s < deque[h]) {
                    // 如果队列依然为空,或药丸用完,或即使使用药丸也无法完成队列头部的任务,则返回false
                    return false;
                }
                --t; // 完成一个任务,队列尾部指针前移
            } else {
                ++h; // 工人直接完成了队列头部的任务,队列头部指针后移
            }
        }
        return true; // 如果所有工人都成功分配了任务,则返回true
    }
};

就到这,铁子们下期见!!!!

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

- 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》

本文属于专栏《构建工业级QPS百万级服务》​​​​​ 1、前置知识 c的内存管理&#xff0c;主要说的是堆内存管理。现代计算机系统中&#xff0c;用户进程的堆内存&#xff0c;由内核映射。 堆内存的来源 主要是通过mmap()函数&#xff0c;在进程的虚拟地址空…

【Linux技术宝典】深入理解Linux基本指令:命令行新手指南

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅Linux技术宝典 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 一、Linux下基本指令1. ls 指令2. pwd指令3. clear指令4. cd指令什么是家目录&#xf…

【AI视野·今日Robot 机器人论文速览 第七十八期】Wed, 17 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Wed, 17 Jan 2024 Totally 49 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Safe Mission-Level Path Planning for Exploration of Lunar Shadowed Regions by a Solar-Powered Rover Authors Olivier L…

【Pandas 统计函数和自定义函数的使用】

文章目录 前言一、统计函数1. 描述性统计2. 直方图 二、自定义函数1. 自定义函数示例 总结 前言 Pandas 是基于 NumPy 的数据分析工具&#xff0c;它提供了各种数据结构&#xff0c;如 Series 和 DataFrame&#xff0c;以及各种功能强大的函数&#xff0c;用于数据的统计、清洗…

随机过程及应用学习笔记(四) 马尔可夫过程

马尔可夫过程是理论上和实际应用中都十分重要的一类随机过程。 目录 前言 一、马尔可夫过程的概念 二、离散参数马氏链 1 定义 2 齐次马尔可夫链 3 齐次马尔可夫链的性质 三、齐次马尔可夫链状态的分类 四、有限马尔可夫链 五、状态的周期性 六、极限定理 七、生灭过…

Android adb使用超级大全

Android adb使用超级大全 ADB&#xff0c;即Android Debug Bridge&#xff0c;是一款强大的工具&#xff0c;对于Android开发/测试人员来说是不可或缺的&#xff0c;同时也是Android设备玩家的好玩具。本文将详细介绍ADB的使用方法。 ADB的基本用法如下&#xff1a; 命令语法…

chatglm3-6b使用

源码地址 GitHub - THUDM/ChatGLM3: ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型 创建环境 conda create -n chatglm36 python3.11.7 修改源码中依赖&#xff0c;使得使用cuda&#xff0c;否则太慢了 pip3 install torch2.1.2 torchvision0.16.2 to…

SpringBoot3 + Vue3 由浅入深的交互 基础交互教学

说明&#xff1a;这篇文章是适用于已经学过SpringBoot3和Vue3理论知识&#xff0c;但不会具体如何实操的过程的朋友&#xff0c;那么我将手把手从教大家从后端与前端交互的过程教学。 目录 一、创建一个SpringBoot3项目的和Vue3项目并进行配置 1.1后端配置: 1.1.1applicatio…

C语言第二十四弹---指针(八)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、数组和指针笔试题解析 1.1、字符数组 1.1.1、代码1&#xff1a; 1.1.2、代码2&#xff1a; 1.1.3、代码3&#xff1a; 1.1.4、代码4&#xff1a; 1…

StringJoiner

JDK8开始有&#xff0c;用来操作字符串&#xff0c;不仅可以提高字符串的操作效率&#xff0c;而且在某些场景使用它操作字符串&#xff0c;代码会更加简洁。 import java.util.StringJoiner;public class Test {public static void main(String[] args) {//StringJoiner的应用…

ChatGPT高效提问—prompt实践(漏洞风险分析-重构建议-识别内存泄漏)

ChatGPT高效提问—prompt实践&#xff08;漏洞风险分析-重构建议-识别内存泄漏&#xff09; 1.1 漏洞和风险分析 ChatGPT还可以帮助开发人员预测代码的潜在风险&#xff0c;识别其中的安全漏洞&#xff0c;而不必先运行它&#xff0c;这可以让开发人员及早发现错误&#xff0…

探索设计模式的魅力:创建型设计模式的比较与决策

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 一、设计模式概览 1.1 创建型模式 二、比较创建型设计模式 1.1 适用场景典型用例 1.2 关键要素与差异对比 1.3 结构图 三、模式选择指南 3.1 场景分析 3.2 决策流程图 四、结语 4.1 优势 4.2 考量因素 一、…

【漏洞扫描】网络空间安全工具—Goby 快速入门使用指南

下载地址 Goby&#xff08;含1322个POC&#xff09; v2.8.9 社区版 介绍 Goby是一款基于网络空间测绘技术的新一代网络安全工具&#xff0c;它通过给目标网络建立完整的资产知识库&#xff0c;进行网络安全事件应急与漏洞应急。 Goby可提供最全面的资产识别&#xff0c;目前…

串行通信的艺术:深入解析UART与奇偶校验

发送数据位是电流传输吗&#xff1f; 在UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;通信中&#xff0c;发送数据位不直接以电流的形式传输。而是通过改变电压水平或者光信号&#xff08;在光纤通信中&#xff09;来表示不同的数据位&#xff08…

C#利用接口实现选择不同的语种

目录 一、涉及到的知识点 1.接口定义 2.接口具有的特征 3.接口通过类继承来实现 4.有效使用接口进行组件编程 5.Encoding.GetBytes(String)方法 &#xff08;1&#xff09;检查给定字符串中是否包含中文字符 &#xff08;2&#xff09;编码和还原前后 6.Encoding.GetS…

[计算机网络]---网络编程套接字

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、基础知识…

数仓建模—数据网格

数据网格 随着数字化时代的到来,近几年数据领域的新技术概念不断涌现,无论是数据湖、湖仓一体、流批一体、存算一体、数据编织抑或数据网格,很多还爬上了Gartner曲线,其中数据网格备受关注,数据网格从字面意思来看挺抽象的,会劝退很多人,但当你深入去理解这个概念时,才…

数据存储以及内存

数据在内存中的存储是因不同的类型而不同的。 但首先我们需要知道的是&#xff0c;在C语言中&#xff0c;数据在内存中的存储是以变量的形式存储的。每个变量都有一个地址&#xff0c;指向内存中的特定位置。变量的值存储在这个地址对应的内存单元中。不同类型的变量在内存中占…

react【三】受控组件/高阶组件/portals/fragment/严格模式/动画

文章目录 1、受控组件1.1 认识受控组件1.2 checkout1.3 selected1.4 非受控组件 2、高阶组件2.1 认识高阶组件2.2 应用1-props增强的基本使用2.3 对象增强的应用场景-context共享2.4 应用2-鉴权2.5 应用3 – 生命周期劫持2.6、高阶组件的意义 3、Portals4、fragment5、StrictMo…

【无标题】Matlab之annotation函数——创建图形注释(箭头、椭圆、矩形)

应用1&#xff1a;创建文本箭头注释 创建一个简单线图并向图窗添加文本箭头。用归一化的图窗坐标指定文本箭头位置&#xff0c;起点为 (0.3,0.6)&#xff0c;终点为 (0.5,0.5)。通过设置 String 属性指定文本说明。 figure plot(1:10) x [0.3 0.5]; y [0.6 0.5]; annotation…