문제 설명
선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.
예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.
위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크나 라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.
선행 스킬 순서 skill과 유저들이 만든 스킬트리1를 담은 배열 skill_trees가 매개변수로 주어질 때, 가능한 스킬트리 개수를 return 하는 solution 함수를 작성해주세요.
제한 조건
- 스킬은 알파벳 대문자로 표기하며, 모든 문자열은 알파벳 대문자로만 이루어져 있습니다.
- 스킬 순서와 스킬트리는 문자열로 표기합니다.
- 예를 들어, C → B → D 라면 CBD로 표기합니다
- 선행 스킬 순서 skill의 길이는 1 이상 26 이하이며, 스킬은 중복해 주어지지 않습니다.
- skill_trees는 길이 1 이상 20 이하인 배열입니다.
- skill_trees의 원소는 스킬을 나타내는 문자열입니다.
- skill_trees의 원소는 길이가 2 이상 26 이하인 문자열이며, 스킬이 중복해 주어지지 않습니다.
입출력 예
skillskill_treesreturn
"CBD" | ["BACDE", "CBADF", "AECB", "BDA"] | 2 |
입출력 예 설명
- BACDE: B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트립니다.
- CBADF: 가능한 스킬트리입니다.
- AECB: 가능한 스킬트리입니다.
- BDA: B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트리입니다.
풀이
function solution(skill, skill_trees) {
let result = 0;
skill_trees.filter((skill_tree) => {
let isCorrect = true;
let learnedSkill = [];
for(var each_skill of skill_tree){
if(skill.indexOf(each_skill) > -1){
for(var i =0; i<skill.indexOf(each_skill); i++){
if(!learnedSkill[skill[i]]){
isCorrect = false;
break;
}
}
learnedSkill[each_skill] = 1;
}
}
if(isCorrect){
result ++;
}
});
return result;
}
빠른 참조를 위해 object를 활용했다.
유저의 스킬트리를 순회하는데, 만약 선행 스킬트리에 존재하는 스킬이라면
선행 스킬을 유저가 배웠는지 여부를 object에서 key 값으로 검사하고 배웠다면 해당 스킬을 object에 삽입한다.
만약 배우지 않았다면 break 후 다음 skill을 탐색한다.
더 빠른 풀이
function solution(skill, skill_trees) {
function isCorrect(n) {
// const test = '[' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('').filter(v => !skill.includes(v)).join('') + ']*';
let test = skill.split('');
for (var i = 0; i < n.length; i++) {
if (!skill.includes(n[i])) continue;
if (n[i] === test.shift()) continue;
return false;
}
return true;
}
return skill_trees.filter(isCorrect).length;
}
내 풀이는 테스트 1번에서 0.17ms가 나왔는데 해당 풀이는 0.1ms이다. 코드의 길이만 봐도 짧고 명료하다..
내 풀이에서는 object를 이용해 배운 스킬인지를 검사했다면
선행 스킬 배열을 shift하며 배운 스킬들은 재차 검사하지 않도록 했다. 똑똑하다..
주요 문법
//배열에 value라는 요소가 있는지 검사한다.
skill.includes(value)
//배열의 첫 번째 요소를 삭제하며 반환한다.
test.shift()
//filter는 element, index, array 순서대로 인수를 넘겨준다.
arr.filter(callbackFunction(element, index, array), thisArg);
'Programming > Algorithm' 카테고리의 다른 글
[JS/알고리즘] 스택/큐 : 다리를 지나는 트럭 (프로그래머스) (0) | 2021.02.06 |
---|---|
[JS/알고리즘] 해쉬 : 베스트앨범 (프로그래머스) (1) | 2021.02.03 |
[JS/알고리즘] 스택/큐 : 기능개발 (프로그래머스) (0) | 2021.01.31 |
[JS/알고리즘] 해시 : 위장 (프로그래머스) (0) | 2021.01.31 |
[JS/알고리즘] 해시 : 완주하지 못한 선수 (프로그래머스) (2) | 2021.01.29 |