https://school.programmers.co.kr/learn/courses/30/lessons/43163
문제 설명
두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.
예를 들어 begin이 "hit", target가 "cog", words가 ["hot","dot","dog","lot","log","cog"]라면 "hit" -> "hot" -> "dot" -> "dog" -> "cog"와 같이 4단계를 거쳐 변환할 수 있습니다.
두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.
제한사항
입출력 예
begin target words return
"hit" "cog" ["hot", "dot", "dog", "lot", "log", "cog"] 4
"hit" "cog" ["hot", "dot", "dog", "lot", "log"] 0
DFS를 활용하면 쉽게 해결할 수 있는 문제입니다.
우선, 문제를 좀 더 편리하게 풀기 위해 words 배열에 있는 값들을 ArrayList에 저장합니다. 그 다음, 이미 변환됐던 단어인지 확인하기 위해 배열을 하나 선언 해줍니다. 마지막으로, 변환 가능한 경우인지를 확인 하는 메서드만 작성하면 문제를 쉽게 해결할 수 있습니다.
import java.util.*;
class Solution {
static int answer, n;
static boolean[] visit;
static List<String> list;
public int solution(String begin, String target, String[] words) {
list = Arrays.asList(words);
answer = Integer.MAX_VALUE;
n = list.size();
visit = new boolean[n];
if(!list.contains(target)) {
return 0;
}
dfs(begin, target, 0);
return answer;
}
static void dfs(String curr, String target, int k) {
if(curr.equals(target)) {
answer = Math.min(answer, k);
return;
}
for(int i = 0; i < n; i++) {
if(visit[i]) continue; // 이미 사용한 단어는 제외
if(!isAvailable(curr, list.get(i))) continue; // 변환 불가능한 경우도 제외
visit[i] = true;
dfs(list.get(i), target, k + 1);
visit[i] = false;
}
}
// 변환 할 수 있는지 확인
static boolean isAvailable(String s1, String s2) {
int cnt = 0;
for(int i = 0; i < s1.length(); i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if(c1 != c2) cnt++;
}
return cnt == 1;
}
}