给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 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]]
自己写的,回溯算法,得出答案不对
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def dfs(start, size, path, res):
if len(path) == size:
res.append(path)
for index in range(start, size): # 这样写循环,导致只能按顺序生成列
dfs(index+1, size, path+[nums[index]], res)
res = []
path = []
size = len(nums)
dfs(0, size, path, res)
return res
官方解,回溯算法
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def dfs(path, size, depth, used, res):
if depth == size:
res.append(path)
for i in range(size):
if used[i] == False:
used[i] = True
dfs(path+[nums[i]], size, depth+1, used, res)
used[i] = False # 深度优先遍历,结束之后,要把used[i]变为False,以便后面遍历,这个很关键
path, res = [], []
used = [False for _ in range(len(nums))]
dfs(path, len(nums), 0, used, res)
return res
也可以这样写,拷贝path,并使用pop()。因为变量 path 所指向的列表 在深度优先遍历的过程中只有一份 ,深度优先遍历完成以后,回到了根结点,成为空列表。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def dfs(nums, size, depth, path, used, res):
if depth == size:
res.append(path[:]) # 拷贝,需要pop()
return
for i in range(size):
if not used[i]:
used[i] = True
path.append(nums[i])
dfs(nums, size, depth + 1, path, used, res)
used[i] = False
path.pop()
size = len(nums)
used = [False for _ in range(size)]
res = []
dfs(nums, size, 0, [], used, res)
return res
回溯法
采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的递归方法来实现,在反复重复上述的步骤后可能出现两种情况:
深度优先搜索 算法(英语:Depth-First-Search,DFS)
是一种用于遍历或搜索树或图的算法。这个算法会 尽可能深 的搜索树的分支。当结点 v
的所在边都己被探寻过,搜索将 回溯 到发现结点 v
的那条边的起始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被访问为止。