math
CHAPTER 30 / 45
읽기 약 2분
FUNCTION
점화식: 재귀를 수학으로
핵심 개념
T(n) = T(n-1) + 1 vs T(n) = 2T(n/2) + n — 마스터 정리·피보나치·메모이제이션.
본문
점화식 = 재귀 함수의 시간복잡도
재귀 함수의 동작을 수식으로 표현:
T(n) = (자기 호출 시간) + (자기 호출 외 시간)
선형: T(n) = T(n-1) + O(1) → O(n)
분할 정복: T(n) = 2T(n/2) + O(n) → O(n log n)
지수: T(n) = T(n-1) + T(n-2) + 1 → O(2^n)단순 점화식 풀이
# T(n) = T(n-1) + 1, T(1) = 1
# = T(n-2) + 1 + 1
# = T(n-3) + 1 + 1 + 1
# = ...
# = T(1) + (n-1) = n
# → O(n)
def linear_recursion(n):
if n == 1:
return 1
return linear_recursion(n - 1) + 1
# 호출 횟수 검증
count = 0
def linear_counted(n):
global count
count += 1
if n == 1:
return 1
return linear_counted(n - 1) + 1
count = 0
linear_counted(100)
print(count) # 100 → O(n) 검증분할 정복 점화식
# T(n) = 2T(n/2) + n (머지 정렬)
# 풀이:
# T(n) = 2T(n/2) + n
# = 2[2T(n/4) + n/2] + n = 4T(n/4) + 2n
# = 4[2T(n/8) + n/4] + 2n = 8T(n/8) + 3n
# = ...
# = 2^k T(n/2^k) + kn
# n/2^k = 1 일 때 종료 → k = log₂ n
# T(n) = n × T(1) + n log n = O(n log n)
# T(n) = T(n/2) + 1 (이진 검색)
# = T(n/4) + 2
# = T(n/8) + 3
# = ...
# = T(1) + log₂ n
# → O(log n)
# T(n) = 2T(n/2) + 1 (이진 트리 순회)
# 풀이: T(n) = 2T(n/2) + 1
# = 4T(n/4) + 3
# = ...
# = 2^k T(n/2^k) + (2^k - 1)
# k = log n → T(n) = n + n - 1 = O(n)마스터 정리 (Master Theorem)
T(n) = a·T(n/b) + f(n) 형태
· a: 자기 호출 횟수
· n/b: 부분 문제 크기
· f(n): 호출 외 작업
세 케이스:
1. f(n) = O(n^c), c < log_b(a) → T(n) = O(n^log_b(a))
2. f(n) = O(n^c), c = log_b(a) → T(n) = O(n^c × log n)
3. f(n) = O(n^c), c > log_b(a) → T(n) = O(f(n))
예시:
머지 정렬: a=2, b=2, f(n)=n (c=1)
log_2(2) = 1 = c → 케이스 2
T(n) = O(n × log n) = O(n log n) ✅
이진 검색: a=1, b=2, f(n)=1 (c=0)
log_2(1) = 0 = c → 케이스 2
T(n) = O(n^0 × log n) = O(log n) ✅
행렬 곱셈: a=8, b=2, f(n)=n² (c=2)
log_2(8) = 3 > c → 케이스 1
T(n) = O(n^3) ✅ (스트라센 알고리즘은 a=7로 줄임)지수 점화식 — 피보나치
# T(n) = T(n-1) + T(n-2) + 1
# 풀이는 복잡 — 황금비 관련
# T(n) ≈ φ^n 여기서 φ = (1+√5)/2 ≈ 1.618
# → O(φ^n) ≈ O(2^n)
def fib_naive(n):
if n <= 2:
return 1
return fib_naive(n - 1) + fib_naive(n - 2)
# 호출 횟수 — 폭발
import sys
sys.setrecursionlimit(10000)
count = 0
def fib_counted(n):
global count
count += 1
if n <= 2:
return 1
return fib_counted(n - 1) + fib_counted(n - 2)
count = 0; fib_counted(20); print(f"n=20: {count}회") # 13529회
count = 0; fib_counted(30); print(f"n=30: {count}회") # 1664079회
count = 0; fib_counted(35); print(f"n=35: {count}회") # 약 1800만회
# n=40+에서는 분 단위 시간메모이제이션 — O(n)으로 단축
def fib_memo(n, cache={}):
if n in cache:
return cache[n]
if n <= 2:
return 1
cache[n] = fib_memo(n - 1) + fib_memo(n - 2)
return cache[n]
# 호출 횟수 — 각 n마다 1번만
count = 0
def fib_memo_counted(n, cache={}):
global count
count += 1
if n in cache:
return cache[n]
if n <= 2:
return 1
cache[n] = fib_memo_counted(n - 1, cache) + fib_memo_counted(n - 2, cache)
return cache[n]
count = 0; fib_memo_counted(100); print(f"n=100: {count}회") # 199회
count = 0; fib_memo_counted(1000); print(f"n=1000: {count}회") # 1999회
# → O(n)
# functools.lru_cache로 자동 메모이제이션
from functools import lru_cache
@lru_cache(maxsize=None)
def fib_lru(n):
if n <= 2:
return 1
return fib_lru(n - 1) + fib_lru(n - 2)
print(fib_lru(100))점화식 → 폐쇄형 (Closed Form)
# 피보나치 폐쇄형 (비넷 공식)
# F(n) = (φ^n - ψ^n) / √5
# φ = (1+√5)/2, ψ = (1-√5)/2
import math
def fib_binet(n):
sqrt5 = math.sqrt(5)
phi = (1 + sqrt5) / 2
psi = (1 - sqrt5) / 2
return round((phi**n - psi**n) / sqrt5)
print(fib_binet(10)) # 55
print(fib_binet(50)) # 12586269025
# O(1) 시간 — 단, 부동소수점 오차로 큰 n에서 부정확다음 챕터
CH.31 "동적 프로그래밍" — 점화식의 가장 강력한 응용.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 재귀 알고리즘의 시간복잡도를 점화식으로 표현하고 마스터 정리로 정확히 도출해줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
한국 코딩 테스트 점화식 문제 Top 10과 각각 마스터 정리 / 메모이제이션 적용 패턴을 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 코드의 모든 재귀 함수에서 시간복잡도를 점화식으로 분석하고 메모이제이션 적용 우선순위를 만들어줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 시니어 면접에서 점화식 풀이 출제 빈도와 한국 IT 대기업 실제 평가 기준을 솔직히 알려줘.
⭐ 이것만 기억하세요
점화식: 재귀를 수학으로는 이 3가지만 확실히 잡으세요
1.점화식 T(n) = T(n-1) + 1은 O(n), T(n) = 2T(n/2) + n은 O(n log n)
2.마스터 정리는 분할 정복 점화식의 시간복잡도를 즉시 도출 — a/b/c 비교
3.다음 챕터 CH.31에서 동적 프로그래밍 — 점화식이 코드로 변환되는 패턴
공유하기
진행도 30 / 45