Leetcode 46. Permutations
题目
解法1:back tracking
这道题应该可以作为回溯法入门最好的讲解例子了,下面引用一段看到的比较好的回溯讲解:
回溯法(backtracking)是优先搜索的一种特殊情况,又称为试探法,常用于需要记录节点状 态的深度优先搜索。通常来说,排列、组合、选择类问题使用回溯法比较方便。 顾名思义,回溯法的核心是回溯。在搜索到某一节点的时候,如果我们发现目前的节点(及 其子节点)并不是需求目标时,我们回退到原来的节点继续搜索,并且把在目前节点修改的状态 还原。这样的好处是我们可以始终只对图的总状态进行修改,而非每次遍历时新建一个图来储存 状态。在具体的写法上,它与普通的深度优先搜索一样,都有 [修改当前节点状态]→[递归子节 点] 的步骤,只是多了回溯的步骤,变成了 [修改当前节点状态]→[递归子节点]→[回改当前节点 状态]。
没有接触过回溯法的读者可能会不明白我在讲什么,这也完全正常,希望以下几道题可以让 您理解回溯法。如果还是不明白,可以记住两个小诀窍,一是按引用传状态,二是所有的状态修 改在递归完成后回改。 回溯法修改一般有两种情况,一种是修改最后一位输出,比如排列组合;一种是修改访问标 记,比如矩阵里搜字符串。
具体到这道题目的解析。首先我们考虑自己小学在做排列组合的时候会怎么做。我想大部分是这么想的,我现在有[1,2,3],那我首先固定1,然后调换2,3的位置,其次固定2,调换1,3,最后固定3,调换1,2。 其实这个过程我们就是在进行DFS。每次固定一个位置代表DFS的一个level。把这种情况推广一下,假设现在数组是[1,2,…,n]。那么首先固定1在第一个位置,在固定1的情况下,这个level包含的情况应该是1后面所有数字的全排列,接下来固定2在1的位置,也就是调换1和2,那么这个level包含的所有情况应该是第二个位置后面的所有排列,以此类推。
不知道讲清楚没有,虽然这道题目非常简单,但是对于深刻理解回溯还是非常有帮助的。具体对于这道题的解法如下:
python代码如下:
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def backtrack(first):
if first == n:
output.append(nums[:])
return
for i in range(first,n):
nums[first],nums[i] = nums[i