Description
In a project, you have a list of required skills req_skills, and a list of people. The ith person people[i] contains a list of skills that the person has.
Consider a sufficient team: a set of people such that for every required skill in req_skills, there is at least one person in the team who has that skill. We can represent these teams by the index of each person.
- For example, 
team = [0, 1, 3]represents the people with skillspeople[0],people[1], andpeople[3]. 
Return any sufficient team of the smallest possible size, represented by the index of each person. You may return the answer in any order.
It is guaranteed an answer exists.
Β
Example 1:
Input: req_skills = ["java","nodejs","reactjs"], people = [["java"],["nodejs"],["nodejs","reactjs"]] Output: [0,2]
Example 2:
Input: req_skills = ["algorithms","math","java","reactjs","csharp","aws"], people = [["algorithms","math","java"],["algorithms","math","reactjs"],["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws","java"]] Output: [1,2]
Β
Constraints:
1 <= req_skills.length <= 161 <= req_skills[i].length <= 16req_skills[i]consists of lowercase English letters.- All the strings of 
req_skillsare unique. 1 <= people.length <= 600 <= people[i].length <= 161 <= people[i][j].length <= 16people[i][j]consists of lowercase English letters.- All the strings of 
people[i]are unique. - Every skill in 
people[i]is a skill inreq_skills. - It is guaranteed a sufficient team exists.
 
Solution
Python3
class Solution:
    def smallestSufficientTeam(self, req_skills: List[str], people: List[List[str]]) -> List[int]:
        N = len(req_skills)
        skillIndex = {x : i for i, x in enumerate(req_skills)}
        dp = {0 : []}
 
        for index, skill in enumerate(people):
            mask1 = sum(1 << skillIndex[lang] for lang in skill)
 
            for mask2, v in list(dp.items()):
                combined = mask1 | mask2
 
                if combined == mask2: continue
 
                if combined not in dp or len(v) + 1 < len(dp[combined]):
                    dp[combined] = v + [index]
 
        
        return dp[(1 << N) - 1]