给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
- 输入: [1,2,3]
- 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
解题思路
-
问题建模:题目要求给出一个数组的所有排列组合,属于典型的全排列问题,这可以用回溯法来解决。回溯法通过递归的方式,依次将数组中的每个元素放入排列中,直到生成一个完整的排列,然后回溯,尝试其他排列。
-
回溯法流程:
- 依次选择未使用的元素,加入当前排列。
- 当排列长度达到
nums
长度时,将当前排列加入结果集。 - 回溯撤销之前的选择,尝试下一个元素,直到遍历完所有可能性。
完整代码如下:
class Solution:
def permute(self, nums):
result = []
self.backtracking(nums, [], [False] * len(nums), result)
return result
def backtracking(self, nums, path, used, result):
if len(path) == len(nums):
result.append(path[:])
return
for i in range(len(nums)):
if used[i]:
continue
used[i] = True
path.append(nums[i])
self.backtracking(nums, path, used, result)
path.pop()
used[i] = False
def permute(self, nums):
result = []
self.backtracking(nums, [], [False] * len(nums), result)
return result
- 这个函数是程序的入口。它接收一个整数数组
nums
,并返回该数组的所有排列组合。 result
是用来保存所有排列的列表。- 调用
self.backtracking(nums, [], [False] * len(nums), result)
执行回溯算法来生成所有排列组合。此函数初始化了空路径path
和一个与nums
等长的布尔数组used
,用来标记数组中的某个元素是否已经被使用过。
def backtracking(self, nums, path, used, result):
if len(path) == len(nums):
result.append(path[:])
return
for i in range(len(nums)):
if used[i]:
continue
used[i] = True
path.append(nums[i])
self.backtracking(nums, path, used, result)
path.pop()
used[i] = False
- 终止条件:
if len(path) == len(nums)
: 当path
的长度与nums
相等时,表示已经找到一个完整的排列,将该排列加入result
。
- 循环构建排列:
for i in range(len(nums))
: 遍历nums
中的每一个元素。if used[i]: continue
: 如果nums[i]
已经在当前排列中使用过(used[i]
为True
),跳过这个元素。- 选择一个元素:
used[i] = True
: 将nums[i]
标记为已使用。path.append(nums[i])
: 将nums[i]
添加到当前排列中。
- 递归调用:
self.backtracking(nums, path, used, result)
: 递归调用自己继续构建排列。
- 回溯:
path.pop()
: 撤销上一步的选择,回溯到上一个状态。used[i] = False
: 将nums[i]
标记为未使用,继续尝试其他可能性。