算法_回溯_全排列

全排列

leetcode链接

1.解法

排列问题也是回溯问题的一种。

所以我们可以先画出树图:
在这里插入图片描述
排列问题和组合问题的区别在于,剩余集合中元素相同时,组合只取其中一种,不考虑顺序问题,而排列则要考虑到顺序问题。例如剩余集合[2,3]时,组合[2,3]、[3,2]是同样的,而排列[2,3]、[3,2]是不同的。

所以由图可知,我们每从(剩余)集合中选择一个数,就要再遍历一次集合,从里面选择没选过的数,所以我们可以用一个数组used来记录哪些数值没选择过,这样一来就可以写下如下代码:

for i in range(len(nums)): # 遍历集合
	if used[i] == 1:
		continue
	
	path.append(nums[i]) # path用来存储当前得到的排列
	used[i] = 1
	递归
	used[i] = 0
	path.pop()

现在按照回溯三部曲来写代码:

  1. 写出函数头和一些辅助变量:

     result = []
     path = []
     used = [0] * len(nums)
    
     def backtracking(nums,used)
    
  2. 写出递归出口:

    由图可知,递归出口就是当取到叶子节点的时候,而叶子节点的特征就是len(path)==len(nums),所以可以这样写递归出口:

     if len(path)==len(nums):
     	path1 = path.copy()
     	result.append(path1)
     	return
    
  3. 写出函数逻辑:

    上面已经分析过了递归逻辑了,这里具体写一下:

     for i in range(len(nums)): # 遍历集合
     	if used[i] == 1:
     		continue
     	
     	path.append(nums[i]) # path用来存储当前得到的排列
     	used[i] = 1
     	backtracking(nums,used)
     	used[i] = 0
     	path.pop()
    

完整代码:

def permute(nums):
    result = []
    path = []
    used = [0]*len(nums)

    def backtracking(nums,used):
        if len(path)==len(nums):
            path1 = path.copy()
            result.append(path1)
            return

        for i in range(len(nums)):
            if used[i] == 1:
                continue

            used[i] = 1
            path.append(nums[i])
            backtracking(nums,used)
            path.pop()
            used[i] = 0

    backtracking(nums,used)
    return result

2.总结

排列问题:需要使用used数组来记录

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值