全排列——回溯算法

68 阅读1分钟

image.png

image.png

代码1:

代码1通过维护每次传入的nums不同从而维护其哪个被使用过,哪个没有,
代码2则是通过传入used——map结构从而记录维护

var res [][]int
func permute(nums []int) [][]int {
    res = [][]int{}
    backTrack(nums,len(nums),[]int{})
    return res
}
func backTrack(nums []int,l int,path []int) {
    if l == 0 {
        p := make([]int,len(path))
        copy(p,path)
        res = append(res,p)
    }
    for i := 0; i < l; i++ {
        cur := nums[i]
        path = append(path,cur)
        nums = append(nums[:i],nums[i+1:]...)
        backTrack(nums,len(nums),path)
        nums = append(nums[:i],append([]int{cur},nums[i:]...)...)
        path = path[:len(path)-1]
    }
}

不用全局变量的代码1

func permute(nums []int) [][]int {
    res := [][]int{}
    backTrack(nums,len(nums),[]int{},&res)
    return res
}
func backTrack(nums []int,l int,path []int,res *[][]int) {
    if l == 0 {
        p := make([]int,len(path))
        copy(p,path)
        *res = append(*res,p)
    }
    for i := 0; i < l; i++ {
        cur := nums[i]
        path = append(path,cur)
        nums = append(nums[:i],nums[i+1:]...)
        backTrack(nums,len(nums),path,res)
        nums = append(nums[:i],append([]int{cur},nums[i:]...)...)
        path = path[:len(path)-1]
    }
}

代码2

  1. nums原数组,path走的路线,组成res的一维数组,res提交的二维数组的答案,used用来记录已经走过的元素
  2. len(path) == len(nums)递归的终止的位置,path走到头形成了第一条答案
  3. for循环用来使元素导入path,used则维护其哪一个已经被导入了,如果已经被使用过了则continue
  4. bt循环出来以后,再次将used相关置为false
func permute(nums []int) [][]int {
    var res [][]int
    used := make(map[int]bool)
    bt(nums, []int{}, &res, used)
    return res
}

func bt(nums, path []int, res *[][]int, used map[int]bool) {
    if len(path) == len(nums) {
        temp := make([]int, len(path))
        copy(temp, path)
        *res = append(*res, temp)
    }
    for i := 0; i < len(nums); i++ {
        if used[i] {
            continue
        }
        used[i] = true
        path = append(path, nums[i])
        bt(nums, path, res, used)
        used[i] = false
        path = path[:len(path)-1]
    }
}