LeetCode 문제 풀이: 46. Permutations (순열)




플랫폼: LeetCode
번호: 46
제목: Permutations (순열)
링크: https://leetcode.com/problems/permutations/
난이도:Medium
고유한 정수들로 이루어진 배열 nums가 주어졌을 때, 가능한 모든 순열(permutations)을 반환하는 함수를 작성하세요. 반환하는 순열의 순서는 상관없습니다.
예시 1:
입력: nums = [1,2,3]
출력: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
예시 2:
입력: nums = [0,1]
출력: [[0,1],[1,0]]
예시 3:
입력: nums = [1]
출력: [[1]]
이 문제는 주어진 숫자들로 만들 수 있는 모든 가능한 순서, 즉 순열을 찾는 것입니다. 저는 이 문제를 해결하기 위해 DFS(Depth-First Search, 깊이 우선 탐색)와 백트래킹(Backtracking) 기법을 사용했습니다.
핵심 아이디어:
순열의 각 자리에 어떤 숫자가 올 수 있는지 탐색합니다.
한 번 사용한 숫자는 해당 순열 내에서 다시 사용하지 않습니다.
DFS를 통해 가능한 모든 숫자 조합을 깊이 탐색해 나갑니다.
백트래킹 과정:
ans 리스트: 현재 만들어지고 있는 하나의 순열을 저장합니다.
result 리스트: 완성된 모든 순열들을 저장합니다.
DFS 함수 (dfs) 동작:
종료 조건: 만약 ans에 담긴 숫자의 개수가 원래 nums 배열의 길이와 같아지면, 하나의 완전한 순열이 만들어진 것입니다. 이 ans를 (복사하여) result에 추가하고 탐색을 종료(return)합니다.
탐색 및 재귀 호출: nums 배열의 각 숫자에 대해 다음을 반복합니다.
선택 조건: 만약 현재 숫자가 아직 ans 리스트에 포함되어 있지 않다면 (즉, 현재 순열에서 아직 사용되지 않았다면), 그 숫자를 선택합니다.
ans.append(num): 선택한 숫자를 ans에 추가합니다.
dfs(): 다음 숫자를 선택하기 위해 DFS 함수를 재귀적으로 호출합니다.
ans.pop(): 재귀 호출이 끝나고 돌아오면 (즉, 현재 숫자로 시작하는 모든 하위 순열 탐색이 완료되면), ans에서 마지막에 추가했던 숫자를 제거(pop)합니다. 이것이 백트래킹단계로, 이전 상태로 돌아가 다른 선택지를 탐색할 수 있게 해줍니다.
이 과정을 통해 모든 가능한 순열을 체계적으로 찾아낼 수 있습니다.
제가 직접 작성한 코드와 주석입니다.
Python
from typing import List
# dfs 알고리즘 이용해 백트레킹
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
self.result = [] # 최종 순열들을 저장할 리스트
self.ans = [] # 현재 만들어지고 있는 하나의 순열을 저장하는 리스트
def dfs():
# 종료 조건: 현재 순열(ans)의 길이가 원본 배열(nums)의 길이와 같으면
# 하나의 완전한 순열이 완성된 것이므로 결과에 추가한다.
if len(self.ans) == len(nums):
self.result.append(self.ans[:]) #...
