Posts 백트래킹으로 순열/조합 구현하기 in Python
Post
Cancel

백트래킹으로 순열/조합 구현하기 in Python

알고리즘 문제를 풀다보면 순열과 조합을 사용하여 모든 경우의 수를 구해봐야할 일이 많습니다. (완전탐색 / 브루트포스)
파이썬에는 itertools 라이브러리에 해당 기능을 제공하지만 코딩테스트 환경에서 모든 경우의 수를 미리 만들어놓고 하나하나 독립적으로 처리하면 시간초과 판정을 받을 수 있습니다.
따라서 백트래킹 기법을 사용하여 경우의 수를 동적으로 만들어가면서 변경점 위주로 처리하는 것이 시간측면에서 유리합니다.


백트래킹 (재귀)

우선 본격적인 코드를 소개하기 전에 완전탐색에 사용되는 백트래킹 기법을 간단하게 소개하겠습니다.

1
2
3
4
5
6
7
8
def back(n):
    if n == 탈출조건:
        행동수행    # (ex. print / max / min / etc...)
        return

    변화주기
    back(n+1)      # 재귀호출
    복원하기

이런 식으로 모든 경우의 수를 차례차례 탐색할 수 있습니다.


1
2
# 순열/조합에 사용할 배열
arr = [1,2,3,4,5]

순열 (nPr)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
visited = [False] * n
picked = []
def perm(n, r):
    if len(picked) == r:
        print(picked)
        return

    for i in range(len):
        if not visited[i]:
            picked.append(arr[i])   # 변화
            visited[i] = True
            perm(n, r)              # 재귀호출
            visited[i] = False
            picked.pop()            # 복원

조합 (nCr)

1
2
3
4
5
6
7
8
9
10
11
# 조합의 경우 visited가 필요없음
picked = []
def comb(n, r, left):
    if len(picked) == r:
        print(picked)
        return

    for i in range(left, n):        # left ~ n까지만 탐색
        picked.append(arr[i])       # 변화
        comb(n, r, i+1)             # 재귀호출 (마지막에 넣었던 index가 left가 된다.)
        picked.pop()                # 복원
This post is licensed under CC BY 4.0 by the author.