美文网首页清风Python力扣算法刷题
力扣每日一题:回溯解法 全排列I & II

力扣每日一题:回溯解法 全排列I & II

作者: 清风Python | 来源:发表于2021-04-21 00:11 被阅读0次

46.全排列

https://leetcode-cn.com/problems/permutations/

难度:中等

题目:

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

示例:

输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

分析

遇到全排列,所有可能等关键字,我们需要考虑DFS、回溯等解法。
这道题算是比较基础的题目,提供两种解法:

  1. python内置函数
  2. DFS 深度优先解题

解题1 内置函数:

from itertools import permutations

class Solution:
    def permute(self, nums):
        return list(permutations(nums))

解题2 DFS:

class Solution:
    def permute(self, nums):
        ret = []
        path = []

        def dfs(li):
            if len(li) == len(path):
                ret.append(path[:])
            for i in li:
                if i not in path:
                    path.append(i)
                    dfs(li)
                    path.pop()
        dfs(nums)
        return ret

47.全排列II

https://leetcode-cn.com/problems/permutations-ii/

难度:中等

题目:

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

示例:

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]
示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

分析

这道题是 46.全排列的进阶版本。

当然,我们可以通过稍微修改46题的临时存储格式,来暴力AC这道题,如解法一。

但解法一种只是进行了单纯的回溯,在剪枝方面做得很不好,多出了很多不必要的循环,导致执行时间较长。
那么,针对不重复的序列,我们应该如何操作呢?

我们只需要对数组进行排序后,多使用一个列表用于记录该数组的数字是否使用过即可。

解题1 暴力回溯:

class Solution:
    def permuteUnique(self, nums):
        ret = []
        path = {}

        def dfs(li):
            if len(li) == len(path) and list(path.values()) not in ret:
                ret.append(list(path.values()))
            for i in range(len(li)):
                if i not in path:
                    path[i] = li[i]
                    dfs(li)
                    path.pop(i)
        dfs(nums)
        return ret

解题2 合理剪枝:

class Solution:
    def permuteUnique(self, nums):
        ret = []
        nums.sort()
        stage = [0 for _ in nums]
        path = []

        def dfs(li):
            if len(li) == len(path):
                ret.append(path[:])
                return

            for i in range(len(li)):
                if stage[i] == 1:
                    continue
                if i > 0 and li[i] == li[i - 1] and stage[i - 1] == 0:
                    continue
                path.append(li[i])
                stage[i] = 1
                dfs(li)
                path.pop()
                stage[i] = 0

        dfs(nums)
        return ret

欢迎关注我的公众号: 清风Python,带你每日学习Python算法刷题的同时,了解更多python小知识。

我的个人博客:https://qingfengpython.cn

力扣解题合集:https://github.com/BreezePython/AlgorithmMarkdown

相关文章

  • 力扣每日一题:回溯解法 全排列I & II

    46.全排列 https://leetcode-cn.com/problems/permutations/[htt...

  • 216. Combination Sum III

    题目 分析 这道题和之前的Combination Sum I II类似,都可以用回溯解法。回溯解法的套路是: ch...

  • 47. 全排列 II、39. 组合总和、40. 组合总和 II

    回溯的题 47. 全排列 II[https://leetcode-cn.com/problems/permutat...

  • Leetcode 46. 全排列

    题目 给定一个没有重复数字的序列,返回其所有可能的全排列。 示例: C++解法 来源:力扣(LeetCode)链接...

  • 排列,组合,子集专题

    排列组合的题用回溯法和递归基本可以解决,总结一下。46.全排列 47.全排列II 47比46多了个序列可重复的条件...

  • 47. 全排列 II

    给定一个可包含重复数字的序列,返回所有不重复的全排列。 示例: 思路 python3解法 来源:力扣(LeetCo...

  • LeetCode 力扣 47. 全排列 II

    题目描述(中等难度) 和上一道题类似,不同之处就是给定的数字中会有重复的,这样的话用之前的算法会产出重复的序列。例...

  • Combination Sum I II之回溯解法

    题目 题目I 题目II 分析 题目I是在一个没有重复数字,但是数字可以重复选择的数组中找到所有累加和为target...

  • 739. 每日温度/46. 全排列

    739. 每日温度 相关标签 : 哈希表 栈 46. 全排列 相关标签: 回溯算法

  • 47.全排列II

    自己解法 这题解法和全排列类似,只用对同层相同的分支进行剪枝,有点忘了在哪剪了,还是放在后面剪比较好理解,回溯完以...

网友评论

    本文标题:力扣每日一题:回溯解法 全排列I & II

    本文链接:https://www.haomeiwen.com/subject/lpaolltx.html