[PCCP] DFS - 순열 구하기 | 파이썬

SangJin Ham·2023년 6월 29일
0
post-thumbnail

코딩테스트 역량 강화 교육(거점형 특화 프로그램)이라는 프로그램에 참여해 공부한 내용입니다.


DFS - 순열 구하기

앞서 공부한 DFS(깊이 우선 탐색)을 사용해 순열 구하기 문제를 풀어보겠다.


문제

10이하의 N개의 자연수가 주어지면 이 중 M개를 뽑아 일렬로 나열하는 방법을 모두 출력합니다.


입력

첫 번째 줄에 자연수 N(3<=N<=10)과 M(2<=M<=N)이 주어집니다.
두 번째 줄에 N개의 자연수가 오름차순으로 주어집니다.

출력

첫 번째 줄에 결과를 출력합니다.
출력순서는 사전순으로 오름차순으로 출력합니다.


입력 예제

3 2

출력 예제

12
13
21
23
31
32

코드

nums = []
def DFS(L, n, m, ch):
    if L == m:
        for num in nums:
            print(num, end = ' ')
        print()
    else:
        for i in range(1, n+1):
            if ch[i] == 0:
                nums.append(i)
                ch[i] = 1
                DFS(L+1, n, m, ch)
                ch[i] = 0

def solution(n, m):
    ch = [0] * (n+1)
    DFS(0, n, m, ch)
                                       
solution(3, 2)

풀이

이 문제는 중복 순열 구하기 문제와 매우 흡사하다.

  • 먼저 루트 노트(0)에서 DFS를 호출하면 먼저 현재 원소의 개수(L)가 m과 동일하냐 묻는다.
    • 동일한 경우 : 중복을 허용하지 않는 하나의 순열이 만들어진 것이므로 nums의 원소들을 출력한다.
    • 동일하지 않는 경우 : 1부터 n만큼 자식 노드를 만든다.
      먼저 inums에 들어있지 않은 경우 즉, 출력할 수열이 중복되지 않는 경우인지 물어본다.
      조건을 만족한다면 자식 노드 i를 순열 numsi를 넣고, ch를 이용해 numsi가 들어있다고 표시한다.
      그 후, 자식 노드 i를 기준으로 또 탐색하기 위해 DFS(L+1)를 호출한다. -> 레벨이 올라간다는 건 그 노드의 자식 노드를 탐색한다는 것을 의미
      이렇게 numsm개의 숫자가 담기게 되면 L == m을 또 만족하므로 출력하고 호출이 종료되며, 그 다음 명령줄인 ch[i] = 0을 실행해 inums에서 빠져나왔다고 알려준다.
      이렇게 반복하다가 중복을 허용하며 m개로 나올 수 있는 모든 순열이 출력하면 탐색을 종료한다.
profile
끄적끄적

0개의 댓글