https://school.programmers.co.kr/learn/courses/30/lessons/43163
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
1. 문제 설명
두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.
- 한 번에 한 개의 알파벳만 바꿀 수 있습니다.
- 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 합니다.
입출력 예
begin / target / words / return
"hit" / "cog" / ["hot", "dot", "dog", "lot", "log", "cog"] / 4
"hit" / "cog" / ["hot", "dot", "dog", "lot", "log"] / 0
입출력 예 설명
예제 #1
문제에 나온 예와 같습니다.
예제 #2
target인 "cog"는 words 안에 없기 때문에 변환할 수 없습니다.
2. 시나리오
- 최소 몇 번의 변환으로 target이 되는지, 최소 거리이기 때문에 BFS를 사용하여 탐색한다.
- 단어들끼리 한 개의 알파벳만 차이나면 바꿀 수 있는 것이므로 양방향 연결하여 Map에 저장해둔다.
- 배열의 최대 길이가 50이므로, for문 2번으로 각 단어끼리 모두 연결할 수 있다. O(N^2) 가능
- 배열 words의 단어들 중 begin과 한 알파벳만 차이나는 단어들을 Node(단어의 인덱스, 1)로 큐에 모두 넣고, 방문 표시한다.
Node는 단어의 인덱스와 거리를 멤버 변수로 가진다. - 큐에서 Node를 하나씩 뽑는다.
- 뽑은 Node의 단어가 target이면, Node의 거리를 반환한다.
- 뽑은 Node의 단어가 target이 아니면, 연결된 단어들 중 방문하지 않은 것들을 Node(단어, 뽑은 Node의 거리 + 1)로 큐에 넣어준다.
- 큐가 비지 않을 동안 반복하는데, 만약 변환할 수 없는 경우는 0을 반환하기 때문에 BFS 함수의 마지막에 0을 반환해준다.
3. 코드
import java.util.*;
class Solution {
static Map<Integer, ArrayList<Integer>> map = new HashMap<>();
static boolean[] visited;
public int solution(String begin, String target, String[] words) {
int answer = 0;
visited = new boolean[words.length];
toMap(words);
return bfs(begin, target, words);
//한개만 다르면 연결되어 있음
}
public void toMap(String[] words) {
for(int i = 0 ; i < words.length; i++) {
map.put(i, new ArrayList<>());
}
for(int i = 0 ; i < words.length - 1; i++) {
String a = words[i];
for(int j = i + 1 ; j < words.length; j++) {
String b = words[j];
int count = 0;
for(int k = 0; k < a.length(); k++) {
if (a.charAt(k) != b.charAt(k))
count++;
}
if (count == 1) {
map.get(i).add(j);
map.get(j).add(i);
}
}
}
}
public int bfs(String begin, String target, String[] words) {
Deque<Node> queue = startDeque(begin, words);
while (!queue.isEmpty()) {
Node poll = queue.pollFirst();
if (words[poll.i].equals(target))
return poll.w;
ArrayList<Integer> linked = map.get(poll.i);
for(int i = 0 ; i < linked.size(); i++) {
if (!visited[linked.get(i)]) {
queue.add(new Node(linked.get(i), poll.w + 1));
visited[linked.get(i)] = true;
}
}
}
return 0;
}
public Deque<Node> startDeque(String begin, String[] words) {
Deque<Node> queue = new ArrayDeque<>();
for(int i = 0 ; i < words.length; i++) {
int count = 0;
for (int j = 0 ; j < begin.length(); j++) {
if (begin.charAt(j) != words[i].charAt(j))
count++;
}
if(count == 1) {
queue.add(new Node(i, 1));
visited[i] = true;
}
}
return queue;
}
public class Node {
int i, w;
public Node (int i, int w) {
this.i = i;
this.w = w;
}
}
}
'알고리즘 고득점 Kit' 카테고리의 다른 글
프로그래머스 주식가격 Java (0) | 2024.04.02 |
---|---|
프로그래머스 아이템 줍기 Java (0) | 2024.03.31 |
프로그래머스 네트워크 Java (0) | 2024.03.31 |
프로그래머스 다리를 지나는 트럭 Java (0) | 2024.03.30 |
프로그래머스 프로세스 Java (0) | 2024.03.30 |