【力扣100】46.全排列

添加链接描述

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        # 思路是使用回溯
        if not nums:
            return []
        
        def dfs(path,depth,visited,res):
            # 出递归的条件是当当前的深度已经和nums的长度一样了,把path加入数组,然后出递归
            if len(nums)==depth:
                res.append(path[:])
                return 
            
            for i in range(len(nums)):
                if visited[i]==False:
                    visited[i]=True
                    path.append(nums[i])
                    dfs(path,depth+1,visited,res)
                    path.pop()
                    visited[i]=False

        visited=[False]*len(nums)
        res=[]
        dfs([],0,visited,res)
        return res                 

思路:

  1. 这是一道很能体现回溯思想的题目,很容易想到这样的解题思路[1]+[2,3],也就是先选出一个,把后面的进行递归

  2. 在选择了[1,2,3]之后,要进行回溯,就是把之前加入path中的弹出,然后再重置标志
    在这里插入图片描述

  3. 回溯结束条件是,当当前depth等于数组长度时,就进行收获操作,这里是否有return都无所谓,因为是对叶子节点加入res的操作

  4. 所以定义的func的参数有:当前深度depth,用来记录当前结果的path,一个visited数组用来排除已经访问过的元素,也就是将已经在路径上的节点排除出去,res用来接收总结果

出递归时,为什么使用path[:]而不是path本身?

  • 变量 path 所指向的列表 在深度优先遍历的过程中只有一份 ,深度优先遍历完成以后,回到了根结点,成为空列表。

引用传递和拷贝(path&&path[:])

  • 在Python中,列表是可变对象,而可变对象函数参数传递时是通过引用传递的方式进行的。这意味着当你将一个列表作为参数传递给一个函数时,函数内部操作的是这个列表对象的引用,而不是列表对象的副本
  • 当你在函数内部修改了传入的列表对象时,这些修改会直接影响到原始列表,因为它们指向同一个对象。这种行为称为引用传递或者叫按引用传递。
def modify_list(some_list):
    some_list.append(4)  # 在传入的列表末尾添加一个元素

my_list = [1, 2, 3]
modify_list(my_list)
print(my_list)  # 输出 [1, 2, 3, 4]

  • 在这个例子中,modify_list函数内部的操作直接影响了原始的my_list列表,因为传递的是my_list的引用。
  • 但是,在回溯或递归等需要对列表进行多次修改并且保存不同状态的情况下,我们可能需要确保每个状态的独立性,避免相互影响。这时候,可以使用list.copy()或[:]切片操作创建列表的副本,以便在函数调用或操作过程中不影响原始列表。
  • 29
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值