[프로그래머스] 단어변환 - js

fgStudy·2022년 3월 28일
0

코딩테스트

목록 보기
46/69
post-thumbnail

이번에 푼 문제는 프로그래머스의 단어변환 문제이다.

코딩테스트 연습 - 단어 변환


문제

문제 설명

두 개의 단어 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
hitcog["hot", "dot", "dog", "lot", "log", "cog"]4
hitcog["hot", "dot", "dog", "lot", "log"]0

예제 설명

이 문제는 BFS로 푸는게 더 효율적인 문제이다.

먼저 예제를 분석하면서 문제의 요구사항에 대해 설명하겠다.

EX 1:

begin : hit
target: cog
words: ["hot", "dot", "dog", "lot", "log", "cog"]

문제에서 words가 ["hot","dot","dog","lot","log","cog"]라면 "hit" -> "hot" -> "dot" -> "dog" -> "cog"와 같이 4단계를 거쳐 변환한다고 설명한다.

우리는 이 문제를 BFS로 풀 것인데, 그 이유에 대해 DFS와 BFS를 비교하며 설명하겠다.


문제 풀이

나는 해당 문제를 BFS로 풀었다. 그 이유는 hit과 cog 사이의 최단 경로를 구하는 문제이기 때문이다.

1. BFS 그래프

BFS의 경우 위의 사진의 화살표 순서로 탐색한다.

  • 사용하는 경우: 두 노드 사이의 최단 경로 혹은 임의의 경로를 찾고 싶을 때 이 방법을 선택
  • 과정: BFS는 인접한 노드들을 전부 탐색한다음, 이 노드들에 인접한 방문하지 않은 노드들을 모두 방문
  • 예제: hit과 인접한 hot, lot을 방문한 다음, 이 노드들에 인접하고 방문하지 않은 dot, log를 방문

문제에서 hit에서 cog로 변환하는 최단 경로를 구하는 것을 목표로 하므로 BFS가 효율적이다.


2. DFS 그래프

반면 DFS의 경우 위의 사진처럼 모든 경로를 탐색한다음 그 중 최단 경로를 구한다.

  • 사용하는 경우: 1) 모든 노드를 탐색하거나 2) 한 쪽 경로를 깊게 파야하는 경우 사용
  • 예제: hit → cog로 변환하는 경로가
    • hot → dot → dog → cog (4)

    • hot → dot → lot → log → cog (5)

      이며 이 중 최단 경로인 “hot → dot → dog → cog (4)”를 리턴


Pseudocode

cnt <- 0= []
if (target이 words에 없으면) return;
[begin, cnt]를 큐에 넣고 추가함 표시

while (큐가 비어있지 않다면)
	w <- 큐에서 가장 앞에 있는 노드
	w를 큐에서 빼주고 방문함 표시
	if (w가 target과 같다면) return cnt;
	for u ∈ N
		if (u가 방문한 노드면) return;
		if (u와 w가 한 글자 차이) then
		  큐에 [u, ++cnt]를 추가하고 추가함 표시

전체 코드

function solution(begin, target, words) {
    let answer = 0;
    let visit = [];
    let queue = [];
    if(!words.includes(target)) return 0;
    queue.push([begin,answer]);
    
    while(queue) {
        let [v, cnt] = queue.shift();
        if (v === target) {
            return cnt;
        }
        words.forEach(word => {
            let notEqual = 0;
            if (visit.includes(word)) return;
            for (let i = 0; i < word.length; i++) {
                if (word[i] !== v[i]) {
                    notEqual++;
                }
            }
            if (notEqual === 1) {
                queue.push([word, ++cnt]);
                visit.push(word);
            }
        });
    }
}
profile
지식은 누가 origin인지 중요하지 않다.

0개의 댓글