Information Security Study

[프로그래머스] 단어변환(level3, BFS) 본문

Programming/JAVA

[프로그래머스] 단어변환(level3, BFS)

gayeon_ 2024. 11. 9. 23:42


BFS 개념 참고

https://gayeon-l.tistory.com/491

 

BFS 개념

BFS: 너비 우선 탐색가까운 노드부터 우선적으로 탐색하는 알고리즘보통 그래프 탐색에 사용두 노드 사이의 최단 경로 또는 임의의 경로를 찾을 때 사용Queue로 구현 BFS의 특징BFS는 시작 정점으

gayeon-l.tistory.com

 

 

문제 설명

두 개의 단어 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 합니다.

 

입출력 예

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 안에 없기 때문에 변환할 수 없습니다.

 

 

 

문제 풀이

import java.util.*;

class Solution {
    public int solution(String begin, String target, String[] words) {
        // target이 words에 없으면 바로 0을 리턴
        if (!Arrays.asList(words).contains(target)) {
            return 0;
        }

        // BFS를 위한 큐 선언
        Queue<String> queue = new LinkedList<>();
        // 각 단어에 대해 방문 여부 체크
        boolean[] visited = new boolean[words.length];
        // 시작 단어인 begin을 큐에 넣고, 0단계부터 시작
        queue.offer(begin);
        int step = 0;

        // BFS 시작
        while (!queue.isEmpty()) {
            int size = queue.size();
            // 현재 단계에서 처리할 모든 단어들
            for (int i = 0; i < size; i++) {
                String current = queue.poll();

                // 현재 단어가 target과 같으면 변환 성공, 단계 반환
                if (current.equals(target)) {
                    return step;
                }

                // words 배열을 순회하며 변환 가능한 단어를 큐에 넣음
                for (int j = 0; j < words.length; j++) {
                    if (!visited[j] && canConvert(current, words[j])) {
                        visited[j] = true;  // 방문 처리
                        queue.offer(words[j]);  // 큐에 변환된 단어 추가
                    }
                }
            }
            // 다음 단계로 넘어감
            step++;
        }

        return 0;  // 변환할 수 없는 경우
    }

    // 두 단어가 한 글자만 다른지 확인하는 함수
    private boolean canConvert(String a, String b) {
        int diffCount = 0;
        for (int i = 0; i < a.length(); i++) {
            if (a.charAt(i) != b.charAt(i)) {
                diffCount++;
            }
        }
        return diffCount == 1;  // 한 글자만 다르면 true 반환
    }
}

 

코드 설명

BFS 큐 초기화

  • 큐를 사용하여 BFS를 수행한다. 처음에 begin 단어를 큐에 넣고 BFS를 시작한다.
  • visited 배열로 이미 방문한 단어를 중복 방문하지 않도록 처리한다.

 

BFS 과정

  • 큐에서 하나의 단어를 꺼내서 그 단어가 target과 같으면 그때의 변환 단계를 반환한다.
  • 각 단어마다 words 배열을 순회하며 변환할 수 있는 단어들(차이가 1인 단어)을 큐에 넣고 방문 처리한다.
  • 변환할 수 있는 단어들을 모두 큐에 넣고 한 단계씩 진행한다.

 

단어 변환 가능 여부 체크

  • 두 단어가 한 글자만 다르면 변환할 수 있다는 조건을 canConvert 함수로 체크한다.
  • diffCount가 1이면 변환 가능하다.

 

종료 조건

  • 큐가 비어 있거나 변환이 불가능한 경우에는 0을 반환한다.