https://programmers.co.kr/learn/courses/30/lessons/49993
선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.
예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.
위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크나 라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.
선행 스킬 순서 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 스킬을 먼저 배워야 합니다. 불가능한 스킬트리입니다.
문제풀이
문제해결
1. 딕셔너리를 만들어서 skill에 있는 알파벳을 키, 밸류는 인덱스로 만든다
{
C : 0,
B : 1,
D : 2
}
2. skill_trees를 하나 뽑기
- "BACDE"
3. skill_trees에 한글자를 딕셔너리의 키로 skill의 순서 인덱스를 확인한다
- check[dic[i]]
- B의 인덱스는 1
4. 일단 확인한 인덱스로 check에 그 인덱스를 true로 변경
- check[1] = true
[[false], [true], [false]]
5. 변경한 인덱스부터 앞에 다 true로 변경되어있는지 확인, 안되어있으면 순서대로 잘못된 스킬트리
- check[1]이 true인데 check[0]이 false이다 ====> 잘못된 스킬트리!
def solution(skill, skill_trees):
count = 0
dic = {}
#스킬 종류와 유지해야하는 순서의 인덱스를 딕셔너리로 저장
#{키=스킬종류 : 밸류=순서번호}
for i in range(len(skill)) :
dic[skill[i]] = i
for skill_tree in skill_trees :
check = [False] * len(skill) #딕셔너리의 키 값으로 스킬트리 순서 유지 확인용
flag = True #플래그 값을 계속 True로 유지해야 올바른 스킬 트리 유지
#스킬 한개씩 쪼개서 비교
for s in skill_tree :
#트리에 스킬셋 관련된 스킬이 포함되어 있는 경우
if s in skill :
check[dic[s]] = True #스킬이 확인되면 check에 해당 순서에 맞게 true로 바꿔줌
#check가 0부터 dic[s]인덱스 앞까지 모두 True로 변환되어 있었어야함(그래야 올바른 스킬테크)
for i in range(dic[s]) :
if check[i] == False :
flag = False
break
if flag == True :
count += 1
return count
자바스크립트 코드
function solution(skill, skill_trees) {
let count = 0;
let dic = {}
//스킬 종류와 유지해야하는 순서의 인덱스를 딕셔너리로 저장
//{키=스킬종류 : 밸류=순서번호}
for (let i = 0; i<skill.length; i++) {
dic[skill[i]] = i
}
//skill_trees의 스킬트리 하나씩 뽑으면서 확인
skill_trees.forEach((skill_tree) => {
let check = new Array(skill.length)
let flag = true
//스킬 한개씩 쪼개서 비교
skill_tree = String(skill_tree).split("")
//트리에 스킬셋 관련된 스킬이 포함되어 있는 경우
skill_tree.forEach((s) => {
if (s !== -1) {
check[dic[s]] = true //스킬이 확인되면 check에 해당 순서에 맞게 true로 바꿔줌
//check가 0부터 dic[s]인덱스 앞까지 모두 True로 변환되어 있었어야함(그래야 올바른 스킬테크)
for(let i = 0; i < dic[s]; i++) {
if (check[i] === undefined ) {
flag = false
break
}
}
}
})
if (flag == true) {
count += 1
}
})
return count;
}
'코테풀이 > 해시' 카테고리의 다른 글
[백준 | 실버2] 4358번 : 생태학 (0) | 2022.08.17 |
---|---|
[백준 | 실버4] 나는야 포켓몬 마스터 이다솜(해시) (0) | 2022.08.03 |
[프로그래머스 | 레벨2] 영어 끝말잇기(딕셔너리) (0) | 2022.04.20 |
[프로그래머스 | 레벨2] 파일정렬(딕셔너리) -> 정답아님! (0) | 2022.04.15 |
[프로그래머스 | 2단계] 모음사전(부분수열, for문 노가다) (0) | 2022.04.12 |