[프로그래머스/깊이,너비 우선 탐색(DFS/BFS)/3] 단어 변환 (JAVA)

진문장·2021년 7월 25일
0

출처: 프로그래머스 코딩테스트 깊이,너비 우선 탐색(DFS/BFS) 3번째 문제
(https://programmers.co.kr/learn/courses/30/lessons/43163)

문제 설명

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

풀이 방법

  1. 순회할때 words배열에 접근했는지 여부를 visited 배열로 정의하고 false로 초기화시킨다.
  2. 주어진 begin 부터 시작해 해당 글자가 변환할 수 있는 모든 단어를 받아온다.
  3. 변환가능한 단어들을 반복문으로 돌리고 그안에 재귀함수를 실행한다.
  4. 재귀함수 실행중 만약 변환가능한 단어중 target이 있으면 종료하고 그동안 실행된 카운트를 return 한다.

소스 코드

import java.util.*;

class Solution {
    private int answerCnt = 0;
    private boolean isFound = false;
    private String target = null;
    
    public int solution(String begin, String target, String[] words) {
        List<String> visited = new ArrayList<String>();
        this.target = target;
        List<String> newWords = Arrays.asList(words);
        search(begin,newWords,visited,1);
        return answerCnt;
    }
    private void search(String str, List<String> words, List<String> visited, int cnt) {
        if ( isFound ) return;
        visited.add(str);
        List<String> convertableWords = getConvertableWords(str,words,visited);
        if ( convertableWords.size() < 1 ) return;
        if ( convertableWords.contains(target) ) {
            answerCnt = cnt;
            isFound = true;
            return;
        }
        for ( String word : convertableWords ) {
            search(word,words,new ArrayList<>(visited),cnt+1);
        }
    }
    private List<String> getConvertableWords(String str,List<String> words,List<String> visited) {
        List<String> convertableWords = new ArrayList<String>();
        for ( String word : words ) {
            if ( visited.contains(word) ) continue;
            if ( !isConvertable(str,word) ) continue;
            convertableWords.add(word);
        }
        return convertableWords;
    }

    private boolean isConvertable(String str, String target) {
        char[] strChars = str.toCharArray();
        char[] targetChars = target.toCharArray();
        int cnt = 0;
        for ( int i = 0; i < strChars.length; i++ ) {
            if ( strChars[i] == targetChars[i] ) {
                cnt++;
            }
        }
        return cnt == strChars.length - 1 ? true : false;
    }
}

후기

그동안 탐색문제들을 어렵게 느꼇었는데 이제는 어느정도 수준의 문제는 풀 수 있을 것같은 자신감을 얻었다.

0개의 댓글