回溯——9.全排列

力扣题目链接

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

示例:

  • 输入: [1,2,3]
  • 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]

解题思路

  1. 问题建模:题目要求给出一个数组的所有排列组合,属于典型的全排列问题,这可以用回溯法来解决。回溯法通过递归的方式,依次将数组中的每个元素放入排列中,直到生成一个完整的排列,然后回溯,尝试其他排列。

  2. 回溯法流程

    • 依次选择未使用的元素,加入当前排列。
    • 当排列长度达到 nums 长度时,将当前排列加入结果集。
    • 回溯撤销之前的选择,尝试下一个元素,直到遍历完所有可能性。

完整代码如下:

class Solution:
    def permute(self, nums):
        result = []
        self.backtracking(nums, [], [False] * len(nums), result)
        return result

    def backtracking(self, nums, path, used, result):
        if len(path) == len(nums):
            result.append(path[:])
            return
        for i in range(len(nums)):
            if used[i]:
                continue
            used[i] = True
            path.append(nums[i])
            self.backtracking(nums, path, used, result)
            path.pop()
            used[i] = False
def permute(self, nums):
    result = []
    self.backtracking(nums, [], [False] * len(nums), result)
    return result
  • 这个函数是程序的入口。它接收一个整数数组 nums,并返回该数组的所有排列组合。
  • result 是用来保存所有排列的列表。
  • 调用 self.backtracking(nums, [], [False] * len(nums), result) 执行回溯算法来生成所有排列组合。此函数初始化了空路径 path 和一个与 nums 等长的布尔数组 used,用来标记数组中的某个元素是否已经被使用过。
def backtracking(self, nums, path, used, result):
    if len(path) == len(nums):
        result.append(path[:])
        return
    for i in range(len(nums)):
        if used[i]:
            continue
        used[i] = True
        path.append(nums[i])
        self.backtracking(nums, path, used, result)
        path.pop()
        used[i] = False
  • 终止条件
    • if len(path) == len(nums): 当 path 的长度与 nums 相等时,表示已经找到一个完整的排列,将该排列加入 result
  • 循环构建排列
    • for i in range(len(nums)): 遍历 nums 中的每一个元素。
    • if used[i]: continue: 如果 nums[i] 已经在当前排列中使用过(used[i]True),跳过这个元素。
    • 选择一个元素
      • used[i] = True: 将 nums[i] 标记为已使用。
      • path.append(nums[i]): 将 nums[i] 添加到当前排列中。
    • 递归调用
      • self.backtracking(nums, path, used, result): 递归调用自己继续构建排列。
    • 回溯
      • path.pop(): 撤销上一步的选择,回溯到上一个状态。
      • used[i] = False: 将 nums[i] 标记为未使用,继续尝试其他可能性。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值