[Programmers] ๋‹จ์–ด ๋ณ€ํ™˜ (Python, BFS)

    ๋ฐ˜์‘ํ˜•

    ๐ŸŒฑ ๋ฌธ์ œ

     

    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

    ์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

    programmers.co.kr

     

    ๐ŸŒฑ ํ’€์ด

    1. ํ•ด๋‹น ๋‹จ์–ด์—์„œ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๋‹จ์–ด ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ (๊ทธ๋ž˜ํ”„ ๋งŒ๋“ค๊ธฐ)

    BFS ํƒ์ƒ‰์„ ํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ์œ„์น˜(ํ˜„์žฌ ๋‹จ์–ด)์—์„œ ๊ฐˆ ์ˆ˜ ์žˆ๋Š”(ํ•œ๊ธ€์ž ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š”) ์œ„์น˜๋ฅผ ๋‹ด์€ ๋ฆฌ์ŠคํŠธ(๋…ธ๋“œ๊ฐ„ ์—ฐ๊ฒฐ ์ •๋ณด๋ฅผ ๋‹ด์€ ๊ทธ๋ž˜ํ”„)๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹จ์–ด ๋ฆฌ์ŠคํŠธ๊ฐ€ hot, dot, dog, log, log, cog์ผ ๋•Œ, ๊ทธ๋ž˜ํ”„์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ €์žฅ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

     

    # ํ•ด๋‹น ๋‹จ์–ด์—์„œ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋‹จ์–ด ์ •๋ณด ์ €์žฅ (๊ทธ๋ž˜ํ”„ ๋งŒ๋“ค๊ธฐ)
    for i in range(len(words)):
        word1 = words[i]
        for j in range(len(words) - i - 1):
            word2 = words[i + j + 1]
            if len([ch for idx, ch in enumerate(word2) if ch != word1[idx]]) == 1:
                graph[i].append(i + j + 1)
                graph[i + j + 1].append(i)
    • ๋‹จ์–ด๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜์”ฉ ๋น„๊ตํ•ด๊ฐ€๋ฉด์„œ ์ธ๋ฑ์Šค๋งˆ๋‹ค ๋น„๊ตํ–ˆ์„ ๋•Œ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๊ธ€์ž์˜ ๊ฐœ์ˆ˜๊ฐ€ 1๊ฐœ์ธ ๋‹จ์–ด์˜ ์ธ๋ฑ์Šค์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋ฌด๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์ด๋ฏ€๋กœ ์–‘์ชฝ ๋ชจ๋‘ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

     

    2. ์‹œ์ž‘์  ์ฐพ๊ธฐ

    ํƒ์ƒ‰์„ ์‹œ์ž‘ํ•  ์‹œ์ž‘์ ์€ ์œ„์—์„œ ๊ทธ๋ž˜ํ”„๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. begin์œผ๋กœ ์ฃผ์–ด์ง„ ๋‹จ์–ด์™€ ๋ชจ๋“  ๋‹จ์–ด๋ฅผ ๋น„๊ตํ•˜๋ฉด์„œ begin๊ณผ ํ•œ๊ธ€์ž๋งŒ ๋‹ค๋ฅธ ๋‹จ์–ด์˜ ์ธ๋ฑ์Šค๋ฅผ start ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    for i in range(len(words)):
        word1 = words[i]
    
        if len([ch for idx, ch in enumerate(begin) if ch != word1[idx]]) == 1:
            start.append(i)

     

    3. BFS ํƒ์ƒ‰ํ•˜๊ธฐ

    for s in start:
        answer.append(bfs(graph, s))
    def bfs(graph, s):
        queue = deque()
        visited = [False for _ in range(len(words))]
        queue.append((s, 1))
        visited[s] = True
    
        while queue:
            v, step = queue.popleft()
            if words[v] == target:
                return step
            for i in graph[v]:
                if visited[i] == False:
                    queue.append((i, step + 1))
                    visited[i] = True
    • start์— ์ €์žฅํ•ด๋†“์€ ๋‹จ์–ด์˜ ์ธ๋ฑ์Šค๋“ค์„ ํ•˜๋‚˜์”ฉ ๋Œ๋ฉด์„œ BFS ํƒ์ƒ‰์„ ํ•ฉ๋‹ˆ๋‹ค.
    • BFS ํƒ์ƒ‰์„ ํ•  ๋•Œ์— queue์— ๊ธ€์ž๊ฐ€ ๋ฐ”๋€ ํšŸ์ˆ˜๋ฅผ ํ•จ๊ป˜ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.
    • queue์—์„œ ๊บผ๋‚ธ ๋‹จ์–ด๊ฐ€ target๊ณผ ๊ฐ™๋‹ค๋ฉด ํ˜„์žฌ๊นŒ์ง€ ๊ธ€์ž๋ฅผ ๋ฐ”๊พผ ํšŸ์ˆ˜(step)์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

     

    ๐ŸŒฑ ์ •๋‹ต

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # programmers ๋‹จ์–ด ๋ณ€ํ™˜
    
    from collections import deque
    
    def solution(begin, target, words):
        answer = []
    
        graph = [[] for _ in range(len(words))]
        start = []
    
        if target not in words:
            return 0
    
        def bfs(graph, s):
            queue = deque()
            nonlocal words
            visited = [False for _ in range(len(words))]
            queue.append((s, 1))
            visited[s] = True
    
            while queue:
                v, step = queue.popleft()
                if words[v] == target:
                    return step
                for i in graph[v]:
                    if visited[i] == False:
                        queue.append((i, step + 1))
                        visited[i] = True
    
        # ํ•ด๋‹น ๋‹จ์–ด์—์„œ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋‹จ์–ด ์ •๋ณด ์ €์žฅ (๊ทธ๋ž˜ํ”„ ๋งŒ๋“ค๊ธฐ)
        for i in range(len(words)):
            word1 = words[i]
            for j in range(len(words) - i - 1):
                word2 = words[i + j + 1]
                if len([ch for idx, ch in enumerate(word2) if ch != word1[idx]]) == 1:
                    graph[i].append(i + j + 1)
                    graph[i + j + 1].append(i)
    
            if len([ch for idx, ch in enumerate(begin) if ch != word1[idx]]) == 1:
                start.append(i)
    
        for s in start:
            answer.append(bfs(graph, s))
    
        if min(answer) == None:
            return 0
        return min(answer)

     

     

    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€