全排列 (Python)

LeetCode链接

回溯 时间复杂度 O(n * n!)

时间复杂度分析:

  1. 第一次从n个数中选 第二次从n - 1个数选… 总共的选择 n!
  2. 递归结束时 复制数组时间复杂度 O(n)
  3. 综合1 2 总复杂度 O(n * n!)

每次将选中的数字挪到左侧 下一次在右侧数字中选择

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        '''
        把 nums数组分为左右两边  维护一个分界索引
        每次把 从剩下的元素中选出的元素挪到左边去
        '''
        n = len(nums)
        res_list = []
        def doit(first):
            if first == n:
                res_list.append(nums[:])
            # 每一层都在右侧剩余元素中选择一个元素
            for i in range(first, n):
                # 选出的元素加入左侧
                nums[i], nums[first] = nums[first], nums[i]
                # 分界索引+1 去下一层
                doit(first + 1)
                # 之后 记得把元素再交换回来 开启下一轮循环
                nums[i], nums[first] = nums[first], nums[i]
        doit(0)
        return res_list

使用相同大小的标记数组来表示之前是否选择过

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res_list = []
        path = []
        nums_len = len(nums)
        # 一个相同大小的标记数组 来标记某个下标是否被选择过
        selected = [False for _ in range(nums_len)]
        def doit():
            if len(path) == nums_len:
                res_list.append(path[:])
                return
            for i in range(nums_len):
                if not selected[i]:
                    # 标记选过
                    selected[i] = True
                    # 添加值
                    path.append(nums[i])
                    doit()
                    # 回滚
                    path.pop()
                    selected[i] = False
        doit()
        return res_list
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值