Algorithm & Data Structure/Programmers

[Programmers]Python_단어 변환

ju_young 2020. 12. 5. 21:36
728x90
문제
문제 설명

두 개의 단어 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 합니다.
코드
def solution(begin, target, words):
    #target이 words안에 없을때 예외처리
    if tartget not in words:
        return 0
        
    answer = []
    prev_words = [begin] #처음은 당연히 begin으로 시작하니 begin이 들어간 리스트를 만들어준다
    
    def dfs(words, begin):
        #prev_words의 마지막 문자가 target이면 변환이 완료된 것이므로 변환 횟수를 answer에 append한다
        if prev_words[-1] == target:
            answer.append(len(prev_words) - 1)
            return
            
        for word in words:
            #words에서 for문이 돌고있기때문에 words를 사용하면 안된다. 그렇기 때문에 deepcopy해준다
            nxt_words = words[:]
            #set을 사용하여 비교를 할시 문제가 있기때문에 한 자 한 자 정성스럽게 비교해준다
            #예로 aab, aba가 있다
            b = list(begin)
            for w in word:
                if w in b:
                    b.remove(w)
            
            #begin의 길이가 1이되면 word와 다른 알파벳이 하나 밖에 없는 것이므로 변환 가능한 것이다
            if len(b) == 1:
                #word는 변환가능한 문자이니 prev_words에 append한다
                prev_words.append(word)
                #또한 word는 사용된 문자이니 deepcopy한 nxt_words에서 지워둔다
                nxt_words.remove(word)
                #word를 begin으로 다음 변환할 문자를 찾는다
                #여기서 words대신 nxt_words를 사용함으로서 words를 deepcopy한 이유가 나온다
                dfs(nxt_words, word)
                #처음에 변환 가능한 word를 찾았던 부분까지 싹다 지워버리고 다음 변환 가능한 word를 찾는다
                prev_words.pop()
        
    dfs(words, begin)
    return min(answer) #최소 변환 수 return

 

진행 과정
예제 #1

begin = "hit"

target = "cog"

words = ["hot", "dot", "dog", "lot", "log", "cog"]

 

1) prev_words = ["hit"]

2) prev_words = ["hit", "hot"]

3) nxt_words = ["dot", "dog", "lot", "log", "cog"]

4) prev_words = ["hit", "hot", "dot"]

5) nxt_words = ["dog", "lot", "log", "cog"]

6) prev_words = ["hit", "hot", "dot", "dog"]

7) nxt_words = ["lot", "log", "cog"]

8) prev_words = ["hit", "hot", "dot", "dog", "log"]

9) nxt_words = ["lot", "cog"]

10) prev_words = ["hit", "hot", "dot", "dog", "log", "lot"]

11) nxt_words = ["cog"]

'

12) prev_words = ["hit", "hot", "dot", "dog", "log"] #더 이상 변환 가능한 문자가 없으므로 삭제 후 이전 값으로 돌아감

 

13) nxt_words = ["hit", "hot", "dot", "dog", "log", "cog"]

14) prev_words = ["lot"]

15) answer = [5]

16) prev_words = ["hit", "hot", "dot", "dog", "log"]

17) prev_words = ["hit", "hot", "dot", "dog"]

 

18) prev_words = ["hit", "hot", "dot", "dog", "cog"]

19) nxt_words = ["lot", log"]

20) answer = [5, 4]

21) prev_words = ["hit", "hot", "dot", "dog"]

22) prev_words = ["hit", "hot", "dot"]

 

23) prev_words = ["hit", "hot", "dot", "lot"]

24) nxt_words = ["dog", "log", "cog"]

25) prev_words = ["hit", "hot", "dot", "lot", "log"]

26) nxt_words = ["dog", "cog"]

27) prev_words = ["hit", "hot", "dot", "lot", "log", "dog"]

28) nxt_words = ["cog"]

29) prev_words = ["hit", "hot", "dot", "lot", "log", "dog", "cog"]

30) nxt_words = []

31) answer = [5, 4, 6]

32) prev_words = ["hit", "hot", "dot", "lot", "log", "dog"]

33) prev_words = ["hit", "hot", "dot", "lot", "log"]

 

34) prev_words = ["hit", "hot", "dot", "lot", "log", "cog"]

35) nxt_words = ["dog"]

36) answer = [5, 4, 6, 4]

37) prev_words = ["hit", "hot", "dot", "lot", "log"]

38) prev_words = ["hit", "hot", "dot", "lot"]

39) prev_words = ["hit", "hot", "dot"] 

40) prev_words = ["hit", "hot"] 

 

41) prev_words = ["hit", "hot", "lot"]

42) nxt_words = ["dot", "dog", "log", "cog"]

43) prev_words = ["hit", "hot", "lot", "dot"]

44) nxt_words = ["dog", "log", "cog"]

45) prev_words = ["hit", "hot", "lot", "dot", "dog"]

46) nxt_words = ["log", "cog"]

47) prev_words = ["hit", "hot", "lot", "dot", "dog", "log"]

48) nxt_words = ["cog"]

49) prev_words = ["hit", "hot", "lot", "dot", "dog", "log", "cog"]

50) nxt_words = []

51) asnwer = [5, 4, 6, 4, 6]

52) prev_words = ["hit", "hot", "lot", "dot", "dog", "log"]

53) prev_words = ["hit", "hot", "lot", "dot", "dog"]

 

54) prev_words = ["hit", "hot", "lot", "dot", "dog", "cog"]

55) nxt_words = ["log"]

56) asnwer = [5, 4, 6, 4, 6, 5]

57) prev_words = ["hit", "hot", "lot", "dot", "dog"]

58) prev_words = ["hit", "hot", "lot", "dot"]

59) prev_words = ["hit", "hot", "lot"]

 

60) prev_words = ["hit", "hot", "lot", "log"]

61) nxt_words = ["dot", "dog", "cog"]

62) prev_words = ["hit", "hot", "lot", "log", "dog"]

63) nxt_words = ["dot", "cog"]

64) prev_words = ["hit", "hot", "lot", "log", "dog", "dot"]

65) nxt_words = ["cog"]

 

66) prev_words = ["hit", "hot", "lot", "log", "dog"] #더 이상 변환 가능한 문자가 없으므로 삭제 후 이전 값으로 돌아감

 

67) prev_words = ["hit", "hot", "lot", "log", "dog", "cog"]

68) nxt_words = ["dot"]

69) asnwer = [5, 4, 6, 4, 6, 5, 5]

70) prev_words = ["hit", "hot", "lot", "log", "dog"]

71) prev_words = ["hit", "hot", "lot", "log"]

 

72) prev_words = ["hit", "hot", "lot", "log", "cog"]

73) nxt_words = ["dot", "dog"]

74) asnwer = [5, 4, 6, 4, 6, 5, 5, 4]

75) prev_words = ["hit", "hot", "lot", "log"]

76) prev_words = ["hit", "hot", "lot"]

77) prev_words = ["hit", "hot"]

78) prev_words = ["hit"]

 

79) return min(answer) = 4

 

와 드럽게 기네...

728x90