๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป Programming/์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ

์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ '์•Œ๊ณ ๋ฆฌ์ฆ˜'

by ๋ญ…์ฆค 2025. 1. 16.
๋ฐ˜์‘ํ˜•

์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ฃผ์–ด์ง„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋‹จ๊ณ„์ ์ธ ์ ˆ์ฐจ์ด๋‹ค. ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํƒํ•˜๋ฉด ์‹œ๊ฐ„๊ณผ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๊ณ , ๋ฌธ์ œ๋ฅผ ๋” ๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ธฐ์— ์•Œ์•„๋‘ฌ์•ผ๊ฒ ์ง€? (๋งจ๋‚  ๊นŒ๋จน๋Š”๋‹ค)


Brute Force

๋ธŒ๋ฃจํŠธํฌ์Šค ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋‹ค ๊ณ ๋ คํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋งค์šฐ ์ง๊ด€์ ์ด๊ณ  ๊ตฌํ˜„ํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ, ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ๋งŽ์„ ๊ฒฝ์šฐ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ ๋งค์šฐ ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฃผ๋กœ ์ œํ•œ์ด ์ ๊ฑฐ๋‚˜, ๋ฌธ์ œ์˜ ํฌ๊ธฐ๊ฐ€ ์ž‘์€ ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๋‹ค.

ํŠน์ง•

  • ๋‹จ์ˆœํ•˜๊ณ  ์ง๊ด€์ : ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›€.
  • ์‹œ๊ฐ„ ๋ณต์žก๋„: ๋ฌธ์ œ์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ O(n^2), O(n!)์™€ ๊ฐ™์€ ๋†’์€ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ.
  • ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์‹œ๋„: ์ตœ์ ํ™”๋œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์‹œ๋„ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ๊ฐ€๋Šฅํ•œ ์กฐํ•ฉ, ์ˆœ์—ด์„ ๋ชจ๋‘ ํƒ์ƒ‰ํ•˜๋Š” ๋ฌธ์ œ.
  • ์ œํ•œ์ด ์ž‘์€ ๋ฌธ์ œ์—์„œ ์ตœ์ ์˜ ํ•ด๋‹ต์„ ๊ตฌํ•  ๋•Œ.
  • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์žˆ์–ด ๊ฐ„๋‹จํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ.

์ฃผ์–ด์ง„ ๋ฐฐ์—ด์—์„œ ๋‘ ์ˆ˜์˜ ํ•ฉ์ด ํŠน์ • ๊ฐ’์ด ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ธŒ๋ฃจํŠธํฌ์Šค๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๋ฐฐ์—ด์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋‘ ๊ฐœ์”ฉ ๋น„๊ตํ•˜๋ฉด ๋œ๋‹ค.

def brute_force_two_sum(nums, target):
    n = len(nums)
    for i in range(n):
        for j in range(i + 1, n):
            if nums[i] + nums[j] == target:
                return (nums[i], nums[j])
    return None

nums = [2, 7, 11, 15]
target = 9
print(brute_force_two_sum(nums, target))  # (2, 7)

 

์ด์ง„ ํƒ์ƒ‰ (Binary Search)

์ด์ง„ ํƒ์ƒ‰์€ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ํŠน์ • ๊ฐ’์„ ์ฐพ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ฐฐ์—ด์„ ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋ฅผ ์ขํ˜€ ๋‚˜๊ฐ€๋ฉฐ, O(log n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค. ๋”ฐ๋ผ์„œ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ์›ํ•˜๋Š” ๊ฐ’์„ ๋น ๋ฅด๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ง•

  • ์‹œ๊ฐ„ ๋ณต์žก๋„: O(log n)
  • ๋ฐฐ์—ด์ด ๋ฐ˜๋“œ์‹œ ์ •๋ ฌ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ์ค‘์•™๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๊ฒ€์ƒ‰ ๋ฒ”์œ„๋ฅผ ์ ˆ๋ฐ˜์”ฉ ๋‚˜๋ˆ„๋ฉด์„œ ํƒ์ƒ‰ํ•œ๋‹ค.
  • ๋ฐ˜๋ณต๋ฌธ ๋˜๋Š” ์žฌ๊ท€์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ๊ฐ’์„ ์ฐพ๋Š” ๋ฌธ์ œ.
  • ๊ตฌ๊ฐ„ ํƒ์ƒ‰ ๋ฌธ์ œ.
  • ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํƒ์ƒ‰ ๋ฐฉ์‹.

๋‹ค์Œ์€ ์ด์ง„ ํƒ์ƒ‰์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ํŠน์ • ๊ฐ’์„ ์ฐพ๋Š” ์ฝ”๋“œ์ด๋‹ค.

def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1  # ๊ฐ’์ด ์—†์œผ๋ฉด -1 ๋ฐ˜ํ™˜

arr = [1, 3, 5, 7, 9]
target = 5
print(binary_search(arr, target))  # 2 (5๋Š” ์ธ๋ฑ์Šค 2์— ์žˆ์Œ)

 

๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Greedy Algorithm)

๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋งค ๋‹จ๊ณ„์—์„œ ์ตœ์ ์˜ ์„ ํƒ์„ ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ „์ฒด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ตœ์ ํ•ด๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ง€์—ญ์ ์œผ๋กœ ์ตœ์ ์ธ ์„ ํƒ์„ ๋ฐ˜๋ณตํ•˜๋ฉฐ ํ•ด๊ฒฐํ•œ๋‹ค. ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ•ญ์ƒ ์ตœ์ ํ•ด๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š์ง€๋งŒ, ๋งŽ์€ ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ง•

  • ๋‹จ๊ณ„๋ณ„๋กœ ์ตœ์ ์˜ ์„ ํƒ์„ ํ•œ๋‹ค.
  • ์ „์—ญ ์ตœ์ ํ•ด๋ฅผ ๊ตฌํ•˜์ง€ ์•Š์ง€๋งŒ, ์ง€์—ญ ์ตœ์  ์„ ํƒ์ด ์ „์ฒด ์ตœ์ ์„ ์ด๋ฃฌ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.
  • ๊ฐ„๋‹จํ•˜๊ณ  ์ง๊ด€์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ, ๊ตฌํ˜„์ด ๋น„๊ต์  ์‰ฝ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๋ฌธ์ œ์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค. ์ผ๋ถ€ ๋ฌธ์ œ์—์„œ๋Š” ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ตœ์ ์˜ ํ•ด๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ (Prim, Kruskal ์•Œ๊ณ ๋ฆฌ์ฆ˜)
  • ํ™œ๋™ ์„ ํƒ ๋ฌธ์ œ
  • ๋™์ „ ๊ตํ™˜ ๋ฌธ์ œ

์ฃผ์–ด์ง„ ๋™์ „๋“ค๋กœ ํŠน์ • ๊ธˆ์•ก์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ตœ์†Œ ๋™์ „ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค. ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•˜์—ฌ ๊ฐ€์žฅ ํฐ ๋™์ „๋ถ€ํ„ฐ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์†Œ ๋™์ „ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

def greedy_coin_change(coins, target):
    coins.sort(reverse=True)  # ํฐ ๋™์ „๋ถ€ํ„ฐ ์‚ฌ์šฉ
    result = 0
    for coin in coins:
        result += target // coin
        target %= coin
    return result

coins = [1, 5, 10, 25]
target = 30
print(greedy_coin_change(coins, target))  # 2 (1 x 25, 1 x 5)

 

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ (Dynamic Programming)

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ(DP)์€ ๋ฌธ์ œ๋ฅผ ๋” ์ž‘์€ ๋ถ€๋ถ„ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„์–ด ํ•ด๊ฒฐํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜์—ฌ ์ค‘๋ณต ๊ณ„์‚ฐ์„ ํ”ผํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ตœ์ ํ™” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๋ฉฐ, ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๋„๋ก ํ•˜์—ฌ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ง•

  • ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜์—ฌ ์ค‘๋ณต ๊ณ„์‚ฐ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
  • ํ•˜์œ„ ๋ฌธ์ œ ํ•ด๊ฒฐ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์œ„ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ์žฌ์‚ฌ์šฉํ•œ๋‹ค.
  • ์žฌ๊ท€์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋˜, ์ด์ „ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization) ๋ฐฉ์‹์œผ๋กœ ์ €์žฅํ•˜์—ฌ ๊ณ„์‚ฐ ํšจ์œจ์„ฑ์„ ๋†’์ธ๋‹ค.
  • ๋ณดํ†ต ํƒ์ƒ‰ ๊ณต๊ฐ„์„ ์ค„์ด๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด
  • ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฌธ์ œ (๋‹ค์ต์ŠคํŠธ๋ผ, ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ)
  • ๋ฐฐ๋‚ญ ๋ฌธ์ œ (Knapsack problem)
  • ๋ฌธ์ž์—ด ํŽธ์ง‘ ๊ฑฐ๋ฆฌ (Levenshtein Distance)

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฌธ์ œ์—์„œ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ค‘๋ณต ๊ณ„์‚ฐ์„ ํ”ผํ•˜๊ณ , ์ด์ „ ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜์—ฌ ํšจ์œจ์ ์œผ๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

# ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ™œ์šฉํ•œ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๊ณ„์‚ฐ
def fib(n):
    dp = [0] * (n + 1)
    dp[1] = 1
    for i in range(2, n + 1):
        dp[i] = dp[i - 1] + dp[i - 2]
    return dp[n]

print(fib(10))  # 55

 

BFS (Breadth-First Search)

BFS(๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰)๋Š” ๊ทธ๋ž˜ํ”„๋‚˜ ํŠธ๋ฆฌ์—์„œ ๋„“์ด ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. BFS๋Š” ์‹œ์ž‘ ๋…ธ๋“œ์—์„œ ๊ฐ€๊นŒ์šด ๋…ธ๋“œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ ํƒ์ƒ‰ํ•˜๋ฉฐ, ํ๋ฅผ ์ด์šฉํ•ด ๊ตฌํ˜„๋œ๋‹ค.

ํŠน์ง•

  • ์‹œ์ž‘ ๋…ธ๋“œ์—์„œ ๊ฐ€๊นŒ์šด ๋…ธ๋“œ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•œ๋‹ค.
  • ํ(Queue)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ๊ฐ ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•œ ํ›„ ๊ทธ์— ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋ฅผ ์ฐจ๋ก€๋กœ ํ์— ๋„ฃ์–ด ํƒ์ƒ‰ํ•œ๋‹ค.
  • ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ์ตœ๋‹จ ๊ฒฝ๋กœ ์ฐพ๊ธฐ: ํŠน์ • ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
  • ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰์ด ํ•„์š”ํ•œ ๋ฌธ์ œ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.
  • ๊ทธ๋ž˜ํ”„์˜ ์—ฐ๊ฒฐ ์š”์†Œ๋ฅผ ์ฐพ๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค.

๋‹ค์Œ์€ BFS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ž˜ํ”„์—์„œ ํŠน์ • ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])

    while queue:
        node = queue.popleft()
        if node not in visited:
            print(node, end=" ")  # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ ์ถœ๋ ฅ
            visited.add(node)
            queue.extend(graph[node] - visited)  # ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋ฅผ ํ์— ์ถ”๊ฐ€

# ๊ทธ๋ž˜ํ”„ ํ‘œํ˜„ (์ธ์ ‘ ๋ฆฌ์ŠคํŠธ)
graph = {
    1: {2, 3},
    2: {1, 4},
    3: {1, 5},
    4: {2},
    5: {3}
}

bfs(graph, 1)  # 1 2 3 4 5

 

DFS (Depth-First Search)

DFS(๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰)์€ ๊ทธ๋ž˜ํ”„๋‚˜ ํŠธ๋ฆฌ์—์„œ ๊นŠ์ด ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. DFS๋Š” ์Šคํƒ(ํ˜น์€ ์žฌ๊ท€ ํ˜ธ์ถœ)์„ ์ด์šฉํ•ด ๊ตฌํ˜„๋œ๋‹ค. DFS๋Š” ๊ฐ€๋Šฅํ•œ ํ•œ ๊นŠ๊ฒŒ ํƒ์ƒ‰ํ•˜๊ณ , ๋” ์ด์ƒ ๊นŠ๊ฒŒ ๊ฐˆ ์ˆ˜ ์—†์œผ๋ฉด ๋‹ค์‹œ ๋Œ์•„์™€ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค.

ํŠน์ง•

  • ์‹œ์ž‘ ๋…ธ๋“œ์—์„œ ๊ฐ€๋Šฅํ•œ ํ•œ ๊นŠ๊ฒŒ ํƒ์ƒ‰ํ•œ๋‹ค.
  • ์Šคํƒ(Stack)์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ์ƒ‰ํ•˜๋ฉฐ, ์žฌ๊ท€๋ฅผ ์ด์šฉํ•œ ๊ตฌํ˜„๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๊ฒฝ๋กœ๊ฐ€ ๊นŠ๊ณ  ๋ณต์žกํ•œ ๊ทธ๋ž˜ํ”„์—์„œ ์œ ์šฉํ•˜๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ ๋ฐ ํŠธ๋ฆฌ ํƒ์ƒ‰์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.
  • ๊ฒฝ๋กœ ์ฐพ๊ธฐ ๋ฐ ๋ฐฑํŠธ๋ž˜ํ‚น ๋ฌธ์ œ์—์„œ ์œ ์šฉํ•˜๋‹ค.
  • ๋ชจ๋“  ๊ฒฝ๋กœ ํƒ์ƒ‰์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

๋‹ค์Œ์€ DFS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ž˜ํ”„์—์„œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    visited.add(start)
    print(start, end=" ")  # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ ์ถœ๋ ฅ

    for neighbor in graph[start]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)

# ๊ทธ๋ž˜ํ”„ ํ‘œํ˜„ (์ธ์ ‘ ๋ฆฌ์ŠคํŠธ)
graph = {
    1: {2, 3},
    2: {1, 4},
    3: {1, 5},
    4: {2},
    5: {3}
}

dfs(graph, 1)  # 1 2 4 3 5

 

์ตœ์†Œ ํž™ (Min Heap)

์ตœ์†Œ ํž™(Min Heap)์€ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ž๋ฃŒ ๊ตฌ์กฐ๋กœ, ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘์€ ๊ฐ’์„ ๊ฐ–๋Š” ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค. ์ตœ์†Œ ํž™์€ ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ํ•ญ์ƒ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ๊ฐ€์ง€๋ฉฐ, ์ด ๊ฐ’์„ ๋น ๋ฅด๊ฒŒ ๊บผ๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ตฌ์กฐ๋Š” ์‚ฝ์ž…๊ณผ ์‚ญ์ œ๊ฐ€ ํšจ์œจ์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋ฉฐ, ์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋œ๋‹ค.

ํŠน์ง•

  • ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ํ•ญ์ƒ ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘์€ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค.
  • ๋ฃจํŠธ ๋…ธ๋“œ๋Š” ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค.
  • ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ ํ˜•ํƒœ๋กœ ๊ตฌํ˜„๋œ๋‹ค.
  • ์‚ฝ์ž…๊ณผ ์‚ญ์ œ๊ฐ€ O(log n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ–๋Š”๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
  • ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๊ฐ™์€ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์šฐ์„ ์ˆœ์œ„ ํ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
  • ํž™ ์ •๋ ฌ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.

ํŒŒ์ด์ฌ์—์„œ๋Š” heapq ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์†Œ ํž™์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. heapq๋Š” ์ตœ์†Œ ํž™์„ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋ฉฐ, ํž™์˜ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ๋น ๋ฅด๊ฒŒ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

import heapq

# ์ตœ์†Œ ํž™์„ ์ด์šฉํ•œ ์˜ˆ์‹œ
heap = []

# ์ตœ์†Œ ํž™์— ๊ฐ’ ์‚ฝ์ž…
heapq.heappush(heap, 3)  # O(log n)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)

# ์ตœ์†Œ ํž™์—์„œ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’ ์ถ”์ถœ
print(heapq.heappop(heap))  # 1 (์ตœ์†Œ๊ฐ’)
print(heapq.heappop(heap))  # 2
print(heapq.heappop(heap))  # 3
๋ฐ˜์‘ํ˜•