JavaScript Solution with explanation
\n/**\n * @param {string[]} req_skills\n * @param {string[][]} people\n * @return {number[]}\n */\nvar smallestSufficientTeam = function(req_skills, people) {\n
```\n/**\n * @param {string[]} req_skills\n * @param {string[][]} people\n * @return {number[]}\n */\nvar smallestSufficientTeam = function(req_skills, people) {\n    \n    const skillIndexMap = new Map();\n    \n    req_skills.forEach((skill, index) => skillIndexMap.set(skill,index) );\n    \n    const skillTeamMap = new Map([[0, []]]);\n    \n    people.forEach( (skills, index) => {\n        \n        let hisSkills = 0;\n                \n        for (const skill of skills) {\n            hisSkills |= 1 << skillIndexMap.get(skill);\n        }\n                \n        for (const [currSkill, team] of skillTeamMap) {\n            \n            const totalSkills = currSkill | hisSkills;\n            \n            if (totalSkills === currSkill) {\n                continue;\n            }\n            \n            if (    \n                !skillTeamMap.has(totalSkills) || \n                team.length + 1 < skillTeamMap.get(totalSkills).length\n            ) {                \n                skillTeamMap.set(totalSkills, [...team, index])\n            }             \n        }\n    });\n        \n    return skillTeamMap.get( (1<<req_skills.length) - 1);\n};\n```\n\n\n**Requirement**: A set of skills and a set of people with some or all of those skills is given. We need to form a team with minimum number of people such that their combined skillset = total skills \n\n**Sample input**:\n\nreq_skills = ["java","nodejs","reactjs"]\npeople = [["java"],["nodejs"],["nodejs","reactjs"]]\n\n**Expected output**:\n\n[0,2]\n\n**Explanation**:\n\nThe total skills can be represented using a bitmask. For doing this, we need to represent each skill using a number. Here, we are making use of the index of the skill in req_skills. \n\n```\nconst skillIndexMap = new Map();\n\nreq_skills.forEach((skill, index) => skillIndexMap.set(skill,index) );\n```\n\n\nThe output will look something like this:\n\n{\n\t"java" => 0\n\t"nodejs" => 1\n\t"reactjs" => 2\n}\n\nThis skillIndexMap can be used to form a bitmask of available skills as below:\n\n```\n"java" \t\t=> \t  1\t(index = 0, shift 1 zero position to the left)\n"nodejs"\t=> \t 10 (index = 1, shift 1 one position to the left)\n"reactjs"\t=>\t100\t(index = 2, shift 1 two positions to the left)\n---------------------------------------------------------------------\ntotal\t\t=>  111\n```\n\n\nNow let\'s move on to the main part: creating the team. \n\nFor doing this, we need a new map - skill to team map. This map uses (bitmask of) target skills as key and the index of people required to form the team as value. \n\nSo what is the minimum number of people required if the target skills is 0? \n**0**. Which means an empty array. This will be our initial entry in the list:\n\n```\nskillTeamMap\n{\n\t0: []\t\n}\n```\n\nNow we will iterate through the people array and convert the skillset of each person to a bitmask. This is saved in hisSkills (intially set to 0).\n\neg: The skills of person at index 2 in our example is ["nodejs","reactjs"]\n\n```\nhisSkills |= 1 << skillIndexMap.get("nodejs");\n=>      0 |= 1 <<  1\n=>      0 |= 10\n=>      10\n```\n\n\nhisSkills has become 10.\n\nLets add "reactjs" to hisSkills:\n\n```\nhisSkills |= 1 << skillIndexMap.get("reactjs");\n=>     10 |= 1 <<  2\n=>     10 |= 100\n=>     110\n\n```\n\nAnd that is the bitmask for skills of person at index 2\n\nAfter forming the bitmask, we will go through each of the available skill in skillTeamMap and try adding hisSkills to available skills and see if there is a difference is the result. Let\'s walk through the example given.\n\nInitially,\n\n```\npeople index = 0 \nskillTeamMap = \n{\n\t0: []\t\n}\n```\n\nhisSkills value of person at index 0 is ["java"] => 1\n\nNow we iterate through each key value pair in skillTeamMap. Currently we have only one entry: 0: []. On adding hisSkills:\n\n```\ncurrSkill = 0\nteam = []\n\nconst totalSkills = currSkill | hisSkills;\n\t\t\t\t  = 0 | 1\n\t\t\t\t  = 1\n```\n\n\nNext we update skillTeamMap with the new totalSkills as key and the combined team formed as value. Before doing this, we need to check whether there is already a team available for the same totalSkill. If yes, the update should be done only if our current team size is less than the existing team size.\n\n```\nif (    \n    !skillTeamMap.has(totalSkills) || \n    team.length + 1 < skillTeamMap.get(totalSkills).length\n) {                \n    skillTeamMap.set(totalSkills, [...team, index])\n} \n```\n\nAfter processing index 0, skillTeamMap looks like:\n\n```\n{\n\t0: [],\n\t1: [0]\n}\n```\n\nLet\'s do a dry run for index 1 as well:\n\n```\npeople index = 1\nskillTeamMap = \n{\n\t0: [],\n\t1: [0]\n}\n```\n\nhisSkills = ["nodejs"] => 10\n\n```\ncurrSkill = 0\nteam = []\nconst totalSkills = currSkill | hisSkills;\n\t\t\t\t  = 0 | 10\n\t\t\t\t  = 10\n\t\t\t\t  = 2 (decimal)\n```\n\nskillTeamMap =\n```\n{\n\t0: [],\n\t1: [0],\n\t2: [1]\n}\n```\n\n```\ncurrSkill = 1, team = [0]\nconst totalSkills = currSkill | hisSkills;\n\t\t\t\t  = 1 | 10\n\t\t\t\t  = 11\n\t\t\t\t  = 3 (decimal)\n```\n\nskillTeamMap = \n\n```\n{\n\t0: [],\n\t1: [0],\n\t2: [1],\n\t3: [0,1]\n}\n```\n\n```\ncurrSkill = 2, team = [1]\nconst totalSkills = currSkill | hisSkills;\n\t\t\t\t  = 10 | 10\n\t\t\t\t  = 10\n```\n\ncurrSkill == hisSkills, skip\n\n```\ncurrSkill = 3, team = [0,1]\nconst totalSkills = currSkill | hisSkills;\n\t\t\t\t  = 11 | 10\n\t\t\t\t  = 11\n```\n\ncurrSkill == hisSkills, skip\n\n\nFinally, we return the value of index 111 (7):\n\n```\nskillTeamMap.get( (1<<req_skills.length) - 1)\n\t=> skillTeamMap.get( (1<<3) - 1)\n\t=> skillTeamMap.get( (1000) - 1)\n\t=> skillTeamMap.get( 8 - 1)  //decimal of 1000\n\t=> skillTeamMap.get( 7 )\n```\n\n
['Dynamic Programming', 'Bitmask', 'JavaScript']