题目描述
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]
解法一:递归 + 回溯
def permutations(nums: list) -> list:
# 定义一个列表,用来存储每一次回溯完成时生成的排列
result = []
def backtrack(nums, tmp):
# 当入参li为空时,表示此次回溯结束,这时候把tmp加入result存起来
if not nums:
result.append(tmp)
return
# 这一步是核心,遍历li每一个元素,然后剔除掉,并把剔除掉的元素li[i]加入到tmp的末尾
for i in range(len(nums)):
backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])
backtrack(nums, [])
return result
可以结合下图理解,求[1, 2, 3]的全排列:
解法二:递归
关键是要找到递进关系 和 递归结束条件。
递进关系:依次挑选元素放在首位,然后对剩余列表全排列
结束条件:剩余列表只有一个元素时返回
def permutations(nums: list):
# 递归结束的条件是只有一个元素时,全排列就是自己, 如[1], 全排列就一个,这时返回[[1]]
if len(nums) <= 1:
return [nums]
res = []
# 遍历nums,依次作为第一个元素, 然后对剩余的进行全排列
for i, num in enumerate(nums):
# 剔除挑选出来的那个元素,组成剩余的列表rest,然后再对rest进行全排列得到rest_permutations
rest = nums[:i] + nums[i + 1:]
rest_permutations = permutations(rest)
# rest_permutations是二维列表 [[], [], []...],所以要遍历它,每次遍历把第一个元素加在前面,然后加入到结果集res中
for rest_res in rest_permutations:
res.append([num] + rest_res)
return res
解法三:插入法
def permutations(nums):
if len(nums) <= 1: # 如果为1个或0个元素直接返回
return [nums]
# 逐个元素的插入法,每次插入新元素到所有旧排列的所有能插入的位置生成新排列
result = [[nums[0]]] # 最开始只有第一个元素
for i in nums[1:]: # 遍历剩余元素 i
tmp_result = []
for tmp_list in result: # 遍历结果集
# 遍历结果集中的列表索引,把剩余元素 i 插入到结果集中
for j in range(len(tmp_list) + 1):
tmp_result.append(tmp_list[:j] + [i] + tmp_list[j:])
result = tmp_result # 成为旧排列
return result