题目来源:https://leetcode-cn.com/problems/permutations/python
给定一个 没有重复 数字的序列,返回其全部可能的全排列。数组
示例:bash
输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
思路:深度优化搜索微信
先看题目,以所给数组 [1, 2, 3] 的全排列为例:app
从上面的状况,能够看出。枚举每一个每一位可能出现的状况,已选择的数字在下面的选择则不能出现。按照这个作法,全部的状况将可以罗列出来。这里其实就是执行一次深度优先搜索,从根节点到叶子节点造成的路径就是一个全排列。优化
按照这种思路,沿用上面的例子,从空列表 []
开始,以 1 开始为例。如今肯定以 1 开始,则列表为 [1]
,如今选择 [2]
和 [3]
之中的一个,先选 2
,最后剩下的只有数字 3
,因此造成全排列 [1, 2, 3]
。spa
已知还有一种状况,也就是 [1, 3, 2]
,那么如何实现从 [1, 2, 3]
到 [1, 3, 2]
的变化。深度优先搜索是如何实现的?实际上是从 [1, 2, 3]
回到 [1, 2]
的状况,撤销数字 3,由于当前层只能选择 3,因此再撤销 2 的选择,这样后面的程序则能在选择 3 的时候后续也能选择 2。code
class Solution: def permute(self, nums: List[int]) -> List[List[int]]: def _dfs(nums, depth, pmt, be_selected, length, ans): # 表示深度优化搜索的深度等于数组长度时,这个时候表示全排列已经生成 # 也就是符合状况的选择已经选择完毕 # 将这个全排列的状况添加到列表中 # 这里须要注意,pmt 在参数传递是引用传递,拷贝一份添加到结果中 if depth == length: ans.append(pmt[:]) return # 开始遍历 for i in range(length): # be_selected,表示原数组中的元素的状态,是否被选择,是为 True,否为 False if not be_selected[i]: # 当元素被选择时,改变状态 be_selected[i] = True # 将元素添加到 pmt 中,以构成后续 pmt.append(nums[i]) # 向下一层进行遍历 _dfs(nums, depth + 1, pmt, be_selected, length, ans) # 遍历结束时,进行回溯,这个时候状态要进行重置 # 如上面说的 `[1, 2, 3]` 到 `[1, 3, 2]` 中变化,要撤销 3,再撤销 2,从新选择 # 状态改变 be_selected[i] = False # 撤销 pmt.pop() length = len(nums) if length == 0: return [] be_selected = [False] * length ans = [] _dfs(nums, 0, [], be_selected, length, ans) return ans
以上就是使用深度优化搜索的思想,解决《46. 全排列》的问题的主要内容,主要须要注意的是状态重置。
欢迎关注微信公众号《书所集录》