【LeetCode】46. 全排列

1 问题

给定一个不含重复数字的数组 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]]

2 答案

自己写的,回溯算法,得出答案不对

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(nums,path):
            if not nums:
                res.append(path)
                return
            for i in range(len(nums)):
                dfs(nums[:i]+nums[i+1:],path+[nums[i]])

        res = []
        dfs(nums, [])
        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

解法3

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        ans = []
        path = [0] * n
        def dfs(i, s):
            if i == n:
                ans.append(path.copy())  # 要copy,否则path修改时,ans也会被修改
                return 
            for x in s:
                path[i] = x
                dfs(i+1, s-{x})
        dfs(0, set(nums))
        return ans

https://leetcode.cn/problems/permutations/solutions/2079585/hui-su-bu-hui-xie-tao-lu-zai-ci-jing-que-6hrh

3 知识点

回溯法
采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的递归方法来实现,在反复重复上述的步骤后可能出现两种情况:

  • 找到一个可能存在的正确的答案;
  • 在尝试了所有可能的分步方法后宣告该问题没有答案。

深度优先搜索 算法(英语:Depth-First-Search,DFS)
是一种用于遍历或搜索树或图的算法。这个算法会 尽可能深 的搜索树的分支。当结点 v 的所在边都己被探寻过,搜索将 回溯 到发现结点 v 的那条边的起始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被访问为止。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LouHerGetUp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值