프로그래머스: 단어 변환

승헌·2022년 4월 5일
0

(문제링크)

문제

두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.

1. 한 번에 한 개의 알파벳만 바꿀 수 있습니다.
2. words에 있는 단어로만 변환할 수 있습니다.

예를 들어 begin이 "hit", target가 "cog", words가 ["hot","dot","dog","lot","log","cog"]라면 "hit" -> "hot" -> "dot" -> "dog" -> "cog"와 같이 4단계를 거쳐 변환할 수 있습니다.

두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 각 단어는 알파벳 소문자로만 이루어져 있습니다.
  • 각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.
  • words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.
  • begin과 target은 같지 않습니다.
  • 변환할 수 없는 경우에는 0를 return 합니다.

입출력 예

begintargetwordsreturn
"hit""cog"["hot", "dot", "dog", "lot", "log", "cog"]4
"hit""cog"["hot", "dot", "dog", "lot", "log"]0

입출력 예 설명
예제 #1
문제에 나온 예와 같습니다.

예제 #2
target인 "cog"는 words 안에 없기 때문에 변환할 수 없습니다.

풀이

begin에서 target이 되는 과정을 트리로 생각했다.

만약 begin: hit, target: cog, words: hot, hig, hiz, dot, lot, log 이라면
한 단계마다 한 단어씩 바꾼다고 할 때 아래처럼 트리로 나타낼 수 있다.

최소 단계를 구해야 하니까, 위 트리처럼 봤을 때 트리의 레벨이 정답이 된다.

begin에서 시작해 한 문자만 바꿔 만들 수 있는 단어들을 구하고, target이 된다면 몇 단계를 거쳤는지 반환하게 했다.

여기서 이미 사용한 word는 다음 단계에서 못 사용하게 해야 한다.

소스코드

// 두 단어가 알파벳 하나 차이로 다르다면 true 반환
function isSimilarStr(str1, str2) {
    let cnt = 0;
    for (let i=0; i<str1.length; i++) {
        if (str1[i] !== str2[i]) cnt++;
        if (cnt > 1) return false;
    }
    if (cnt === 0) return -1;
    return true;
}

function solution(begin, target, words) {
    // words에 target이 없으면 0 반환
    if (!words.includes(target)) return 0;
    
    // visited: 방문한 단어, base: 비교할 기준이 되는 단어, step: 단계
    let visited = [], base = [begin], step = 0;
    while (visited.length < words.length) {
        // next: 해당 단계에서 base와 유사한 단어들을 모아놓은 배열
        let next = [];
        
        // base 단어를 기준으로 words 단어들 비교
        for (let i=0; i<base.length; i++) {
            for (let j=0; j<words.length; j++) {
                // words 문자가 방문한 문자가 아니며 base와 유사하다면
                if (!visited.includes(words[j]) && isSimilarStr(base[i], words[j])) {
                    next.push(words[j]);
                    visited.push(words[j]);
                }
            }
        }
        
        // 유사한 단어가 없다면, 이어질 수 없으므로 끝남
        if (next.length < 1) return 0;
        
        // 유사한 단어들 중에 target이 있다면 step 반환
        step++;
        if (next.includes(target)) return step;
        
        // 기준을 next 값으로 갱신
        base = next;
    }
    
    return 0;
}
profile
https://heony704.github.io/ 이리콤

0개의 댓글

관련 채용 정보