Leetcode 1125:最小的必要团队
作为项目经理,你规划了一份需求的技能清单 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]
输入:req_skills = ["algorithms","math","java","reactjs","csharp","aws"], people = [["algorithms","math","java"],["algorithms","math","reactjs"],["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws","java"]]
输出:[1,2]
思路:dp加二进制表示技能种类。
1、二进制表示技能:题目的技能数目<=16,完全可以用1,表示第一种技能,10表示第二种技能,100表示第三种技能,,以此类推 int完全可以容纳。进而我们可以用一个数字来表示当前拥有的技能总数,像5=4+1,就是拥有了技能1和技能3。1<<skNum -1就是表示拥有了所有的技能。以此来创建动态规划的数组。
2、动态规划:我们遍历每个人的技能,根据每个人的技能去更新dp的值。
状态:dp[state] 表示掌握技能的状态为state时,需要的最少人数。根据上面的举例:dp[0] =1 ; dp[1] = 1; dp[3] = 2;
list[state] 表示这个状态下 人员的编号。
转移方程: dp[nextState] = min(dp[nextState],dp[ preState | p[i] ] + 1 ) ; (p[i] 是第i个人掌握技能的状态,preState | p[i] == dp[nextState] ) ;
结果要覆盖所有的技能,那么我们要求的状态就是 (1<<(skill_num)-1) ,所以最少的人数就是dp[1<<(skill_num) -1];
结果就是list[ ( 1<<skill_num ) - 1] ,人员编号的状态 随着dp的转移而转移。
代码如下:
public int[] smallestSufficientTeam(String[] req_skills, List<List<String>> people) {int pNum = people.size();int skNum = req_skills.length;int[] dp = new int[1<<skNum];List<Integer>[] res = new ArrayList[1<<skNum];Map<String,Integer> map = new HashMap<>();for(int i=0;i<skNum;i++){map.put(req_skills[i],1<<i);}for(int i=0;i<(1<<skNum);i++){dp[i]=-1;res[i] = new ArrayList<>();}dp[0]=0;for(int i=0;i<pNum;i++){int sk=0;for(String str:people.get(i))sk|=( map.get(str) == null ? 0 : map.get(str) );//获取当前人的技能类for(int st=0;st<(1<<skNum);st++){if(dp[st]==-1) continue;int newState = sk|st;if(dp[newState]==-1||dp[st]+1<dp[newState]){dp[newState] = dp[st] + 1; //更新人员数量res[newState].clear();res[newState].addAll(res[st]); //更新人员的编号res[newState].add(i);}}}int[] result = new int[res[(1<<skNum)-1].size()];for(int i=0;i<result.length;i++){result[i] = res[(1<<skNum)-1].get(i);}return result;}
运行结果如下:
希望可以帮到大家,有不懂的地方可以提问。
Leetcode 1125:最小的必要团队相关推荐
- Leetcode 1125:最小的必要团队(超详细的解法!!!)
作为项目经理,你规划了一份需求的技能清单 req_skills,并打算从备选人员名单 people 中选出些人组成一个「必要团队」( 编号为 i 的备选人员 people[i] 含有一份该备选人员掌握 ...
- leetcode 64. 最小路径和(递归 / 动态规划解法图解)(Java版)
题目 leetcode 64. 最小路径和 提示: m == grid.length n == grid[i].length 1 <= m, n <= 200 0 <= grid[i ...
- LeetCode 1631. 最小体力消耗路径(DFS + 二分查找)
文章目录 1. 题目 2. 解题 1. 题目 你准备参加一场远足活动.给你一个二维 rows x columns 的地图 heights ,其中 heights[row][col] 表示格子 (row ...
- LeetCode 64最小路径和65有效数字66加一
原创公众号:bigsai 专注于Java.数据结构与算法,一起进大厂不迷路! 关注后回复进群即可加入力扣打卡群,欢迎划水.近期打卡: LeetCode打卡 52八皇后Ⅱ&53最大子序和& ...
- LeetCode 1981. 最小化目标值与所选元素的差(DP)
文章目录 1. 题目 2. 解题 1. 题目 给你一个大小为 m x n 的整数矩阵 mat 和一个整数 target . 从矩阵的 每一行 中选择一个整数,你的目标是 最小化 所有选中元素之 和 与 ...
- LeetCode 1942. 最小未被占据椅子的编号(set)
文章目录 1. 题目 2. 解题 1. 题目 有 n 个朋友在举办一个派对,这些朋友从 0 到 n - 1 编号. 派对里有 无数 张椅子,编号为 0 到 infinity . 当一个朋友到达派对时, ...
- LeetCode 483. 最小好进制(二分查找)
文章目录 1. 题目 2. 解题 1. 题目 对于给定的整数 n, 如果 n 的 k(k>=2)进制数的所有数位全为1,则称 k(k>=2)是 n 的一个好进制. 以字符串的形式给出 n, ...
- LeetCode 963. 最小面积矩形 II
文章目录 1. 题目 2. 解题 1. 题目 给定在 xy 平面上的一组点,确定由这些点组成的任何矩形的最小面积,其中矩形的边不一定平行于 x 轴和 y 轴. 如果没有任何矩形,就返回 0. 示例 1 ...
- LeetCode 939. 最小面积矩形(哈希)
文章目录 1. 题目 2. 解题 1. 题目 给定在 xy 平面上的一组点,确定由这些点组成的矩形的最小面积,其中矩形的边平行于 x 轴和 y 轴. 如果没有任何矩形,就返回 0. 示例 1: 输入: ...
最新文章
- 【Pandas库】(5) 索引操作--增、删
- Leetcode 201. 数字范围按位与 解题思路及C++实现
- apache-tomcat-6.0.39的配置
- 非洲瓜哇JAVA布的特点_java语言的基本特性以及编程细节
- 错误记录集锦(遇到则记下)
- inputdstream mysql_【sparkStreaming】将DStream保存在MySQL
- (1)Linux进程调度
- 【无机纳米材料科研制图——Photoshop 0403】PS使用索套工具和魔棒工具框出选区
- 深秋云台行:少爷的云台山之旅
- VsCode设置一行代码固定长度
- postgresql之integerset
- 形容java工作者的句子_形容工作态度的句子
- QQ群怎么快速封群,如何举报骗子QQ群可以使之封群?
- linux中来宾用户权限,linux权限分配
- NLP词性分析,实体分析,句法树构造(依存句法树分析)
- python抓取小红书_小红书很难爬?最新爬取方法教给你啦~
- Privacy Amplification by Decentralization
- Matlab缩进与空格
- GX、LS型螺旋输送机结构新颖 噪声低
- CDH6.1.0环境搭建 完成后 登录admin账户失败