선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.
예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.
위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크나 라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.
선행 스킬 순서 skill과 유저들이 만든 스킬트리1를 담은 배열 skill_trees가 매개변수로 주어질 때, 가능한 스킬트리 개수를 return 하는 solution 함수를 작성해주세요.
C → B → D 라면 "CBD"로 표기합니다| skill | skill_trees | return |
|---|---|---|
| "CBD" | ["BACDE", "CBADF", "AECB", "BDA"] | 2 |
skillIndexDic는 skill의 <스킬이름, 순서>를 저장하고
skillTreeIndexDic는 skill_trees의 <스킬이름, 순서>를 저장한다.
skill_trees를 탐색하면서 skill_tree의 스킬이 skillIndexDic에 포함되어있는지와 순서가 같은지 체크하고 아니라면 isSeqRight를 false 로 바꾸어준다.
isSeqRight가 true 이면 스킬 트리 순서가 올바른 스킬트리이므로 count를 증가시킨다.
코드 개선을 해보던 중 너무 과하게 자료구조를 사용해서 푼거 같아서 아래의 코드로 개선해보았다.
skill을 index로 포인터를 두고 skill_trees의 문자열을 탐색한다.
skill에 포함된 문자일경우 skill[index] 와 비교를한다.
맞으면 다음 skill을 지정하고 틀릴 경우 isSeqRight를 false로 해준다.
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public int solution(string skill, string[] skill_trees) {
int answer = -1;
Dictionary<char, int> skillIndexDic = new Dictionary<char, int>(); // skill의 각 <스킬이름,순서> 저장
Dictionary<char, int> skillTreeIndexDic = new Dictionary<char, int>(); // skill_trees의 <스킬이름,순서> 저장
int count = 0;
// skill_trees와 비교하기위한 skill의 스킬이름과 인덱스 매핑
for (int i = 0; i < skill.Length; i++)
{
skillIndexDic.Add(skill.ElementAt(i), i);
}
foreach (string skill_tree in skill_trees)
{
skillTreeIndexDic.Clear();
bool isSeqRight = true; // 스킬순서가 맞는지
int index = 0; // 스킬 순서
for (int i = 0; i < skill_tree.Length; i++)
{
// 현재 스킬이 skill에 포함되어 있다면 추가
if (skillIndexDic.ContainsKey(skill_tree[i]))
{
skillTreeIndexDic.Add(skill_tree.ElementAt(i), index++);
}
}
foreach (KeyValuePair<char,int> skillPair in skillIndexDic)
{
// skill의 스킬이름이 skill_trees에 있는지 && 두 스킬이 같은 순서인지
if (skillTreeIndexDic.ContainsKey(skillPair.Key) && !skillTreeIndexDic[skillPair.Key].Equals(skillPair.Value)) isSeqRight = false;
}
if (isSeqRight) count++;
}
answer = count;
return answer;
}
}
------
using System;
public class Solution {
public int solution(string skill, string[] skill_trees) {
int answer = -1;
int count = 0;
foreach (string skill_tree in skill_trees)
{
int index = 0;
bool isSeqRight = true;
foreach (char c in skill_tree)
{
if (!skill.Contains(c))
{
continue;
}
if (skill[index] == c)
{
index++;
}
else
{
isSeqRight = false;
break;
}
}
if(isSeqRight) count++;
}
answer = count;
return answer;
}
}