LeetCode-46.全排列

题目描述

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
LeetCode-46.全排列_第1张图片

解题思路

这是一个回溯问题,我们可以采用dfs构建排列树来求解。用path来表示一次排列的结果集,used表示输入序列nums中每个元素的使用情况,res表示最终包含所有全排列集合的结果集,depth表示排列树的层数。
以测试用例:[1,2,3]为例,构建如下排列树

LeetCode-46.全排列_第2张图片
上面提到,我们用path保存一次排列的结果,那么当每次构建到叶子节点时,那么就说明我们找到了一个排列,那么就可以把这个排列即path保存到res中,接下来进行回溯。以上图最左边的子树的叶子为例(即[1,2,3]),需要回溯到[1,2],我们需要做的事情有两个:
1.在path中删除回溯前的最后一个点,这里即为3
2.把这个点的used状态列表中相应元素置False
接着,回溯到上一层,即[1]。
简单来说,在进行排列时,我们需要:
1.在path中记录
2.在used中标记
在回溯时,我们需要:
1.删除path中的记录
2.删除在used中的标记

代码实现(py3)

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

# 深度优先搜索
def dfs(nums, depth, path, used, res):
    # 已经到了叶子节点
    if(depth == len(nums)):
        res.append(path.copy())
        return
    for i in range(len(nums)):
        if used[i]:
            continue
        # 还没被选过
        path.append(nums[i])
        used[i] = True
        dfs(nums, depth + 1, path, used, res)
        # 回溯
        path.pop()
        used[i] = False
class Solution:
    def permute(self, nums):
        path = []
        used = []
        for _ in range(len(nums)):
            used.append(False)
        depth = 0
        res = []
        if len(nums) == 0:
            return res
        dfs(nums, depth, path, used, res)
        return res

你可能感兴趣的:(算法,leetcode,算法,dfs)