8. 재귀 & 백트래킹
8. 재귀 & 백트래킹
1. 재귀 (Recursion) 란?
- 함수가 자기 자신을 호출하는 것
- 수학적으로 반복되는 구조를 표현할 때 유용
예: 팩토리얼
n! = n × (n-1)! 5! = 5 × 4 × 3 × 2 × 1
1.1 재귀의 기본 구조
1
2
3
4
def 함수():
if 종료조건: # 반드시 필요!
return
함수() # 자기자신을 호출
1.2 예제 1 - 팩토리얼
1
2
3
4
5
6
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
print(factorial(5)) # 120
⚠️ 중요한 포인트
- 종료 조건(
if n == 0
) 없으면 무한 루프로 터진다. - 콜스택(Stack)에 함수들이 쌓였다가 하나씩 빠지면서 계산된다.
1.3 예제 2 - 피보나치 수열
f(n) = f(n-1) + f(n-2), 단 f(0) = 0, f(1) = 1
1
2
3
4
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
⚠️ 이건 동일한 계산을 반복하기때문에 비효율적
나중에 DP
에서 메모이제이션으로 최적화함
2. 백트래킹 (Backtracking) 이란?
- 모든 경우의 수를 시도하며 정답을 찾는 알고리즘
- “되면 하고, 안 되면 돌아간다(Backtrack)”
- 대표 예: 완전탐색 + 가지치기
2.1 백트래킹 기본 구조
1
2
3
4
5
6
7
8
9
def backtrack(상태):
if 정답 조건:
처리
return
for 선택 in 가능한지 선택지:
if 유효한 선택인지 검사:
선택 적용
bactrack(다음 상태)
선택 취소 (원상복구)
2.2 예제 1 - 1부터 N까지 모든 순열 구하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def bactkrack(path, used):
if len(path) == N:
print(path)
return
else:
for i in range(1, N+1):
if not used[i]:
used[i] = True
backtrack(path + [i], used)
used[i] = False
return
N = int(input())
used = [False] * (N+1)
bactrack([], used)
입력: 3
1
2
3
4
5
6
7
8
[ ]
┌───────────────────┬───────────────────┐
[1] [2] [3]
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
[1,2] [1,3] [2,1] [2,3] [3,1] [3,2]
| | | | | |
[1,2,3] [1,3,2] [2,1,3] [2,3,1] [3,1,2] [3,2,1]
출력:
1
2
3
4
5
6
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
3. 재귀 vs 백트래킹
항목 | 재귀 | 백트래킹 |
---|---|---|
정의 | 자기 자신 호출 | 재귀 + 가지치기 |
목적 | 반복 계산 | 모든 경우 탐색 |
예시 | 팩토리얼, 피보나치 | 순열, N-Queen, 미로 탐색 |
중요 요소 | 종료 조건 | 유효성 검사 + 백트래킹(복구) |
This post is licensed under CC BY 4.0 by the author.