나의 풀이
문제 풀기전 했던 생각
// 문제
/*
선행스킬은 조건 이 참이어야 배울 수 있다.
skill -> 1이상 20 이하인 배열 중복 x
skill_trees > 중복 x 스킬을 나타내는 문자열 , 길이가 2이상 26이하인
데이터가 크지 않으니 거의 제한 x
모두 중복이 없다.
return 가능한 스킬트리의 개수
return number
*/
// 설계
/*
skil 배열을 먼저 만들어서 해당 각 스킬트리마다 해당 스킬이 나오면 하나씩 제거
즉 배열로 arr[0]으로 판단
if(선행 스킬이 필요한 스킬이 아니지?) continue
if(현재 스킬을 배우기 위한 선행 스킬을 안 배웠지?) break
*/
이 문제는 break를 꼭 사용해야겠다고 생각했다.
풀이 코드
function solution(skill, skill_trees) {
let count = skill_trees.length
skill_trees.forEach((skillTree) => {
const skillStack = [...skill]
for (let i = 0; i< skillTree.length; i++){
if(!skill.includes(skillTree[i])) continue
if(skillStack.shift() !== skillTree[i]){
count -= 1
break
}
}
})
return count
}
includes와 인덱스 접근은 string에서도 가능하니 배열을 남발하지 말자!
for문은 break를 사용하기위해 사용했다. break를 사용한 이유는 올바르지 않은 스킬트리의 스킬이 포함되어있는 순간 그 뒤는 볼필요도 없기 때문이다.
다른 사람 풀이 보면서 개선할 점이 보였다.
`i`의 범위를 skillTree로 할 필요가 없다.
만약 선행스킬이 필요한 모든 스킬들이 다 나왔다면 나머지는 선행스킬이 필요없는 스킬이니 굳이 체크할 필요가 없다.
따라서 skill.length로 제한하면 더 효율적이다.
예를들어 `Skill = ABC` 문자열이 'ABCDEFGHI' 이라고하면 A,B,C 모두 체크했으면 굳이 뒷부분은 체크할 필요가 없다.
다른 사람 풀이
풀이 1
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;
}
오 나랑 같은 생각을 한 사람이 있었다.
풀이 2
function solution(skill, skill_trees) {
var answer = 0;
var regex = new RegExp(`[^${skill}]`, 'g');
return skill_trees
.map((x) => x.replace(regex, ''))
.filter((x) => {
return skill.indexOf(x) === 0 || x === "";
})
.length
}
정규표현식을 이렇게도 사용할 수 있다
'알고리즘 > 프로그래머스 - JS' 카테고리의 다른 글
[프로그래머스] level.2 영어 끝말잇기 (0) | 2023.06.30 |
---|---|
[프로그래머스] level.2 모음사전 (0) | 2023.06.29 |
[프로그래머스] level.2 방문 길이 (0) | 2023.06.28 |
[프로그래머스 - JS,PYTHON] level.3 정수 삼각형 (0) | 2023.06.21 |
[프로그래머스] level.1 기사단원의 무기 ❗️(약수) (0) | 2023.06.19 |