https://leetcode.cn/problems/permutations/description/

这是一道回溯问题,全排列本身有阶乘个答案,固定了最高位之后,后面的依次位进行全排列。所以可以想到:

  1. 大概需要一个for循环来遍历每一个位置,但是每个位置的数字不能是一样的,并且前面用过了后面就不能再用了。
  2. 需要让各个数字在每一个位置都尝试一遍

以上两个加起来发现需要用递归来解决,递归可以解决在解决后面的数字时前面的数字保持不变,并且需要不断地进行回溯尝试


以下是一个普通的回溯解法,用一个visited数组来记录数字有没有被用过。

递归里面首先,如果我们生成的排列数已经用完了所有的数字,说明这一把递归已经到最深了,就可以保存答案退出了,并且这里要注意,答案往里面加的时候,要用浅拷贝或者深拷贝,浅拷贝是成本最低的,深拷贝是最保险的。如果不用这俩拷贝,相当于只放了个引用,原数组一改,答案也改了。


接下来,如果没用完,那么就需要排列,我们对每一个数字都应该在每一个位置上进行探测,如果之前用过了就跳过,如果之前没用过,就把他放到结果后面,然后再继续递归往深走,但是退出来之后要把之前试的数字取消掉,因为可能那个位置还能放其他数字,不只是放某一个。


在递归之前,打个标,证明已经开始用这个数字了,递归之后,要把这个数字重新改为没用过

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        visited = [False] * len(nums)

        res = []
        self.backtrack(nums, [], res, visited)

        return res
    def backtrack(self, nums, current, res, visited):
        if len(current) == len(nums):
            res.append(current[:])
        else:
            for i in range(len(nums)):
                if not visited[i]:
                    current.append(nums[i])
                    visited[i] = True
                    self.backtrack(nums, current, res, visited)
                    current.pop()
                    visited[i] = False