【LeetCode】46. 全排列

leetcode

 

算法思路​

采用​​回溯算法​​解决全排列问题,核心思想是递归探索所有可能的排列路径:

  1. ​路径记录​​:维护当前已选择的元素路径
  2. ​选择列表​​:通过标记数组记录可用元素,确保每个元素只使用一次
  3. ​递归终止条件​​:当路径长度等于原数组长度时,记录完整排列

​实现代码​

func permute(nums []int) [][]int {
    res := [][]int{}
    visited := make([]bool, len(nums))
    path := []int{}
    
    var backtrack func()
    backtrack = func() {
        // 终止条件:路径长度等于数组长度
        if len(path) == len(nums) {
            tmp := make([]int, len(path))
            copy(tmp, path)
            res = append(res, tmp)
            return
        }
        
        // 遍历选择列表
        for i := 0; i < len(nums); i++ {
            if visited[i] { // 跳过已使用的元素
                continue
            }
            
            // 做选择
            visited[i] = true
            path = append(path, nums[i])
            
            // 进入下一层决策树
            backtrack()
            
            // 撤销选择
            visited[i] = false
            path = path[:len(path)-1]
        }
    }
    
    backtrack()
    return res
}

​代码解析​

  1. ​初始化结构​

    • visited 数组标记元素是否已被使用
    • path 切片记录当前路径状态
  2. ​递归核心逻辑​

    • ​终止条件​​:当路径长度等于原数组长度时,复制当前路径到结果集
    • ​遍历选择​​:每次选择未使用的元素加入路径,并标记为已访问
    • ​回溯操作​​:递归返回后撤销当前选择,恢复标记状态
  3. ​避免引用陷阱​
    使用 copy(tmp, path) 深拷贝路径,防止后续操作修改已存储结果


​复杂度分析​

指标说明
​时间复杂度​ O(n×n!) 需要生成n!个排列,每个排列复制耗时O(n)
​空间复杂度​ O(n) 递归栈深度最大为n,标记数组占用O(n)

​示例验证​

func main() {
    // 示例1:[1,2,3]
    fmt.Println(permute([]int{1,2,3})) // 输出6种排列组合
    
    // 示例2:[0,1]
    fmt.Println(permute([]int{0,1}))   // 输出[[0,1],[1,0]]
    
    // 示例3:[1]
    fmt.Println(permute([]int{1}))      // 输出[[1]]
}

​关键优化点​

  1. ​标记数组代替删除操作​
    相比通过删除元素生成子数组的方式,标记数组可避免频繁切片操作带来的性能损耗

  2. ​闭包实现回溯​
    利用Golang闭包特性直接访问外层变量,简化参数传递逻辑

  3. ​内存预分配优化​
    可预先计算排列总数 factorial(len(nums)),初始化结果集容量以减少扩容开销


​与其他方法对比​

方法优点缺点适用场景
​回溯标记法​ 时间复杂度最优 需要额外标记数组 标准全排列场景
​元素交换法​ 节省标记数组空间 破坏原数组顺序 内存敏感场景
​库函数实现​ 代码简洁 依赖语言特性 快速验证场景

​边界处理​

  1. ​空数组处理​​:当输入 nums 为空时直接返回空切片
  2. ​单元素数组​​:直接返回 [[元素值]]
  3. ​大数阶乘优化​​:当n较大时需要考虑内存分配策略

​总结​

该实现基于标准回溯算法,通过标记数组管理选择列表,能够高效生成全排列结果。

posted @ 2025-04-04 16:25  云隙之间  阅读(12)  评论(0)    收藏  举报