2023-09-10:用go语言编写。作为项目经理,你规划了一份需求的技能清单 req_skills,
并打算从备选人员名单 people 中选出些人组成一个「必要团队」
( 编号为 i 的备选人员 people[i] 含有一份该备选人员掌握的技能列表)。
所谓「必要团队」,就是在这个团队中,
对于所需求的技能列表 req_skills 中列出的每项技能,
团队中至少有一名成员已经掌握。可以用每个人的编号来表示团队中的成员:
例如,团队 team = [0, 1, 3] 表示掌握技能分别为
people[0],people[1],和 people[3] 的备选人员。
请你返回 任一 规模最小的必要团队,团队成员用人员编号表示。
你可以按 任意顺序 返回答案,题目数据保证答案存在。
输入:req_skills = ["java","nodejs","reactjs"], people = [["java"],["nodejs"],["nodejs","reactjs"]]。
输出:[0,2]。
来自左程云。
答案2023-09-10:
大体步骤如下:
1.首先,我们对 reqSkills 进行排序,获得排序后的技能列表。这是为了后续方便进行比较。例如,将 ["java", "nodejs", "reactjs"] 排序为 ["java", "nodejs", "reactjs"]。
2.初始化变量 n 为 reqSkills 的长度,变量 m 为 people 的长度,并创建一个长度为 m 的整数数组 statuses 用于记录每个人的技能状态。
3.对于每个人,我们通过比较技能列表和排序后的 reqSkills 列表,来确定他们掌握的技能状态。首先,将该人的技能列表排序。然后使用双指针法,一个指针指向排序后的 reqSkills 列表,另一个指针指向该人的技能列表。比较两个指针指向的技能,如果相等,则表示该人掌握了该技能,将对应的状态位置为1,并将两个指针都向后移动一位;如果 reqSkills[p1] 小于 skill[p2],则将指向 reqSkills 的指针向后移动一位;否则将指向技能列表的指针向后移动一位。重复这个过程直到其中一个指针超出范围。
4.将每个人的技能状态记录在 statuses 数组中。
5.创建一个二维数组 dp,其中 dp[i][j] 表示从第 i 个人开始,技能状态为 j 时,所需的最小团队人数。初始化 dp 数组的所有元素为 -1。
6.调用递归函数 process,该函数的参数包括:people 数组,技能列表的长度 n,当前处理的人员下标 i,当前的技能状态 status,以及 dp 数组。
7.在递归函数 process 中,首先判断当前技能状态是否已经满足所有需求,即 status 是否等于 (1
8.接下来,判断是否已经遍历了所有人员,即 i 是否等于 people 数组的长度。如果是,说明无法满足所有需求,并返回一个较大的值,这里使用 1
9.然后,判断 dp 数组中是否已经记录了当前人员和技能状态的最小团队人数,如果是,直接返回该值。
10.在递归函数中,我们有两个递归调用,第一个是继续尝试从下一个人员开始不增加人员的情况,即调用 process(people, n, i+1, status, dp),将返回的值保存在变量 p1 中。
11.第二个递归调用是尝试从下一个人员开始增加当前人员的情况,即调用 process(people, n, i+1, status|people[i], dp),将返回的值保存在变量 p2 中。注意,这里的参数 status|people[i] 表示将当前人员的技能状态添加到当前技能状态中。
12.如果 p2 不等于 1
13.将 ans 保存在 dp 数组中以便下次使用,并返回 ans。
14.在主函数中,根据返回的最小团队人数 size,创建一个大小为 size 的整数数组 ans 和一个指示 ans 数组下标的变量 ansi。
15.初始化变量 i 为0,status 为0,用于记录当前处理的人员下标和技能状态。
16.如果 status 不等于 (1
17.如果满足上述两个条件之一,将 i 添加到 ans 数组中,并将 ansi 自增1。然后将当前人员的技能状态添加到当前技能状态中。
18.无论是否满足条件,将 i 自增1。
19.执行完循环后,返回 ans 数组作为结果。
总的时间复杂度为O(m * (2^n)),额外空间复杂度为O(m * (2^n))。
go完整代码如下:
在这里插入图片描述rust完整代码如下:
在这里插入图片描述c++完整代码如下:
在这里插入图片描述c完整代码如下:
在这里插入图片描述
领取专属 10元无门槛券
私享最新 技术干货