[프로그래머스] 스킬트리 / Level 2 / C#

알재·2025년 11월 25일

코딩 테스트

목록 보기
73/80

링크

문제링크

문제

선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.

예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.

위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.

선행 스킬 순서 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

해결

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;
    }
}
profile
저장소

0개의 댓글