【力扣日记】046 全排列 | 回溯算法

本文深入解析全排列算法,提供了一种基于递归的实现方法,通过for循环与递归调用,有效地生成给定序列的所有可能排列。同时,对比了不同实现方式的效率,为读者提供了理解和应用全排列算法的清晰路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

算法思路

数学上的全排列总数很容易计算,即是阶乘。考虑如何通过算法列举出所有的排列组合呢?

最简单的应该是for循环的嵌套,但是序列很长时就难以嵌套,所以采用递归。依然是一个for循环,进入循环后将当前变量pop出列表,然后进入递归,继续pop,直到列表为空。然后开始返回,每一层返回都将当层pop出的元素重新insert进序列。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n=len(nums)
        def Sum(ls,n,A=[],K=[]):
            for i in ls:
                x = ls.index(i)
                y=ls.pop(x)
                A.append(y)
                Sum(ls,n,A,K)
                if len(A)==n:K.append(A[:])
                ls.insert(x,y)
                A.pop()
            return K
        return Sum(nums,n)

这是一个粗糙的递归算法。虽然最好成绩

执行用时 :40 ms, 在所有 Python3 提交中击败了86.42%的用户
内存消耗 :13.4 MB, 在所有 Python3 提交中击败了53.38%的用户
————————————————————————————

这里抄一个大佬的解答(代码更加简洁):

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        def backtrack(nums, tmp):
            if not nums:
                res.append(tmp)
                return
            for i in range(len(nums)):
                backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])
        backtrack(nums, [])
        return res

递归部分如下:

        def backtrack(nums, tmp):
            if not nums:
                res.append(tmp)
                return
            for i in range(len(nums)):
                backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])

和我的思路是一致的,但是更加巧妙,只是多个切片操作得到的时间复杂度并不低。

————————
2020/04/25 晴。打卡 全排列。

现在回过头来做回溯算法好简单。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        def helper(ls,t=[]):
            if not ls:
                res.append(t)
            for i in range(len(ls)):
                helper(ls[:i]+ls[i+1:],t+[ls[i]])
        res=[]
        helper(nums)
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值