function solution(begin, target, words) {
const visited = [];
let queue = [];
// words에 target이 없으면 단어를 변환할 수 없다.
if (!words.includes(target)) return 0;
// begin(root)과 deps를 큐에 넣어준다.
queue.push([begin, 0]);
while (queue.length !== 0) {
// 현재 단어와 deps를 꺼낸다.
const [currentWord, deps] = queue.shift();
// 현재 단어가 target과 일치하면 deps를 반환한다.
if(currentWord === target) return deps;
// 현재 단어와 words의 각 단어를 비교한다.
words.forEach((word) => {
if(isOneCharDifference(currentWord, word) && !visited.includes(word)) {
visited.push(word); // 방문 처리
queue.push([word, deps + 1]); // 단어와 deps를 queue에 넣어준다.
}
})
}
// words를 전부 순회 했는데도 단어를 변환할 수 없다면 0 반환한다.
return 0;
}
// 한 번에 한 개의 알파벳만 바꿀 수 있는지 확인
const isOneCharDifference = (word1, word2) => {
let count = 0;
for(let i = 0; i < word1.length; i++) {
if(word1[i] !== word2[i]) count++;
}
return count === 1 ? true : false;
}
너비 우선 탐색으로 루트 노드에서 시작하여 인접한 노드부터 탐색하는 알고리즘
queue를 이용
탐색 수행 시 O(n)의 시간 복잡도
최단거리를 구하는 문제에서 이용
⇒ begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾는 문제이므로 BFS 적용
노드 탐색 순서
예제
const bfs = (graph, start, visited) => {
const q = [];
q.push(start);
visited[start] = true;
while (q.length !== 0) {
const v = q.shift();
console.log(v);
for(const cur of graph[v]){
if(!visited[cur]){
q.push(cur);
visited[cur] = true;
}
}
}
}
const graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7],
]
const visited = [...Array(9).fill(false)];
bfs(graph, 1, visited);
아래와 같이 단어를 한글자씩 자르는 방법을 생각함
const sliceWord = (word, index) => {
const wordToArray = word.split('');
return wordToArray.slice(index, index + 1).join('');
}
이 후 단어의 각 글자를 비교하는 과정과, 한 번에 한 개의 알파벳만 바꿀 수 있는지 확인하는 과정에서 막힘
다른 풀이들을 참고함
const isOneCharDifference = (word1, word2) => {
let count = 0;
for(let i = 0; i < word1.length; i++) {
// 두 단어의 각 인덱스의 글자를 비교하여 다르다면 count에 1을 더한다.
if(word1[i] !== word2[i]) count++;
}
// 한 번에 한 개의 알파벳만 바꿀 수 있으므로 count가 1이 아닐 경우 false를 반환한다.
return count === 1 ? true : false;
}
⇒ 해당 문제는 BFS의 기본 틀에 문제의 조건만 추가하면 풀 수 있는 문제이다.
visited
)를 배열로 하지 않고 Set
객체를 이용하여 구현하는 방법도 있다.참고