๐Ÿ“š Study/Baekjoon

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค | dfs/bfs | ๋‹จ์–ด๋ณ€ํ™˜

์œฐ๊ฐฑ 2025. 10. 9. 03:24

https://school.programmers.co.kr/learn/courses/30/lessons/43163

 

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

SW๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ํ‰๊ฐ€, ๊ต์œก์˜ Total Solution์„ ์ œ๊ณตํ•˜๋Š” ๊ฐœ๋ฐœ์ž ์„ฑ์žฅ์„ ์œ„ํ•œ ๋ฒ ์ด์Šค์บ ํ”„

programmers.co.kr

 

2026.04.01

zip ํ•จ์ˆ˜ ์‚ฌ์šฉ์ด ์—ฌ์ „ํžˆ ๋ฏธ์ˆ™ํ–ˆ๊ณ ,,

bfs ์ž์ฒด ๊ตฌํ˜„์€ ๋‚˜์˜์ง€ ์•Š๊ฒŒ ํ–ˆ๋‹ค. visited๊ฐ€ ์ง‘ํ•ฉ์ด ๋  ์ˆ˜ ์žˆ๋‹ค๋Š”๊ฑด ๋ชฐ๋ž์ง€๋งŒ

(bfs๋Š” 1. queue ๊ตฌํ˜„ 2. visited ์ •์˜ 3. while 4. popleft 5. ์ข…๋ฃŒ์กฐ๊ฑด 6. ์ธ์ ‘ํ•œ ๋…ธ๋“œ 7. ์กฐ๊ฑด ๋งŒ์กฑํ•˜๋ฉด queue์— ๋„ฃ๊ณ  ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌ)

from collections import deque
# ํ•œ ๋‹จ์–ด๋งŒ ๋‹ค๋ฅธ์ง€ ์ฒดํฌํ•˜๋Š” ํ•จ์ˆ˜
def validate(w1, w2):
#     if w1 == w2:
#         return False
    
#     diff = 0
#     for i in range(len(w1)):
#         if w1[i] != w2[i]: # ํ•œ ๋‹จ์–ด์”ฉ ๋น„๊ตํ•˜๊ธฐ
#             diff += 1
#             if diff > 1: # ์ด๋ฏธ ๋‘ ๋‹จ์–ด ์ด์ƒ์ด ๋‹ค๋ฅด๋ฉด ๋” ๋Œ์ง€ ๋ง๊ณ  ๋๋‚ด๊ธฐ
#                 break
#     return (diff == 1)
    return sum(a != b for a, b in zip(w1,w2)) == 1

# ์‹œ์ž‘ ๋‹จ์–ด๋กœ๋ถ€ํ„ฐ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ๋‹จ์–ด ์ฐพ๊ธฐ
def curr_to_next(curr,words):
    next_list = []
    for i in range(len(words)):
        if validate(curr, words[i]):
            next_list.append(words[i])
    return next_list

def bfs(begin,target,words):
    queue = deque([(begin,0)])
    visited = set()
    
    while queue:
        word, cnt = queue.popleft()
        # ์ข…๋ฃŒ ์กฐ๊ฑด
        if word == target:
            return cnt
        
        for next_word in curr_to_next(word, words):
            if next_word not in visited: # ์‚ฌ์šฉํ–ˆ๋˜ ๋‹จ์–ด๊ฐ€ ์•„๋‹ˆ๋ฉด
                queue.append((next_word,cnt+1))
                visited.add(next_word) # ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌ
    
    return 0 # 2. ์ค‘๊ฐ„ ์—ฐ๊ฒฐ ๋‹ค๋ฆฌ๊ฐ€ ์—†์„ ๋•Œ
    
    
def solution(begin,target,words):
    # begin -> target์œผ๋กœ์˜ ์ตœ๋‹จ๊ฑฐ๋ฆฌ
    # ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†์„ ๋•Œ๋Š” 0์„ return
        # 1. words ์•ˆ์— taget์ด ์—†์„ ๋•Œ
        # 2. ์ค‘๊ฐ„ ์—ฐ๊ฒฐ ๋‹ค๋ฆฌ๊ฐ€ ์—†์„ ๋•Œ
    # [๊ตฌํ˜„ ๋ฐฉ๋ฒ•]
        # begin ๋‹จ์–ด๋กœ๋ถ€ํ„ฐ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ๋กœ ๊ฐ€์•ผ ํ•จ (bfs)
        # ๊ทธ ์ค‘์— ์ข…๋ฃŒ์กฐ๊ฑด์ด target์ด๋ž‘ ๊ฐ™์„ ๋•Œ ๋ฉˆ์ถ”๋Š” ๊ฒƒ
        
    if target not in words:
        return 0 # 1. words ์•ˆ์— taget์ด ์—†์„ ๋•Œ
    
    return bfs(begin,target,words)

 

 

 


from collections import deque
def near_words(a, b):
    different = 0
    for i in range(len(a)):
        if a[i] != b[i]:
            different += 1
    if different == 1:
        return True
    else:
        return False
    
def make_graph(graph, begin, words):
    for i in range(len(words)):
        if near_words(begin, words[i]):
            graph[0].append(i+1)
            
    for i in range(len(words)):
        for j in range(i+1, len(words)):
            if near_words(words[i], words[j]):
                graph[i+1].append(j+1);graph[j+1].append(i+1)
                
def bfs(graph, begin_idx, target_idx, visited):
    queue = deque()
    queue.append((begin_idx,0))
    visited[begin_idx] = True
    while queue:
        v, cnt = queue.popleft()
        if v == target_idx:
            return cnt
        for next_v in graph[v]:
            if not visited[next_v]:
                queue.append((next_v, cnt+1))
                visited[next_v] = True
    return 0

def solution(begin, target, words):
    if target not in words:
        return 0
    
    graph = [[] for _ in range(len(words)+1)]
    make_graph(graph, begin, words)
    visited = [False] * (len(words)+1)
    
    answer = bfs(graph, 0, words.index(target)+1, visited)
    return answer

 

๋ณต์žกํ•˜๊ฒŒ ํ‘ผ ์ด์œ  
(1) zip ํ•จ์ˆ˜๋ฅผ ๊นŒ๋จน์Œ
(2) idx์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•๋ฐ–์— ๋ชฐ๋ผ์„œ ๊ทธ๋ž˜ํ”„ ์ˆœํšŒํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์ง‘ํ•ฉ ์ด์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ํ•ด๊ฒฐ๋  ๋ฌธ์ œ์˜€์Œ

 

from collections import deque
def near_words(a, b):
    diff = sum(1 for x,y in zip(a,b) if x!=y)
    return diff == 1

def solution(begin, target, words):
    if target not in words:
        return 0
    
    queue = deque([(begin,0)])
    visited = set()
    
    while queue:
        word, cnt = queue.popleft()
        if word == target:
            return cnt
        for next_word in words:
            if next_word not in visited and near_words(word,next_word):
                queue.append((next_word,cnt+1))
                visited.add(next_word)