leetcode_回溯法合集
目录:
46. 全排列
Difficulty: 中等
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
Solution1 普通递归
Language: Go
func permute(nums []int) [][]int {
if len(nums) == 1 {
return [][]int{nums}
}
var ret [][]int // 结果
for k, v := range nums {
// 1. 提取出当前位
// eg: [1, 2, 3] 提取出[1, 3]
tmp := make([]int, len(nums)-1)
copy(tmp, nums[:k])
copy(tmp[k:], nums[k+1:])
// 2. 拿去求排列 [1, 3] [3, 1]
sub := permute(tmp)
// 3. 结果放入res返回
for _, s := range sub {
// res = [[1,3,2], [3,1,2]]
res = append(res, append(s, v))
}
}
return res
}
Solution2 回溯
Language: Go
func permute(nums []int) [][]int {
if len(nums) == 1 {
return [][]int{nums}
}
l := len(nums)
res := [][]int{}
for i := 0; i < l; i++ {
// [1, 2, 3] 比如把2提取出来
tmp := make([]int, l-1)
copy(tmp, nums[:i])
copy(tmp[i:], nums[i+1:])
// tmp此时为[1,3]
// 把[1,3]拿过去排列,结果肯定是[1,3] [3,1]
sub := permute(tmp)
for _, v := range sub {
// 遍历[1,3] [3,1], 把 2 加到后面
res = append(res, append(v, nums[i]))
}
}
return res
}
func permute(nums []int) [][]int {
if len(nums) == 1 {
return [][]int{nums}
}
l := len(nums)
var (
res [][]int // 返回结果
tmp = make([]int, 0, l) // 中间值
tk = make(map[int]bool, l) // 记录已经使用的数字
)
return trackBack()
}
func trackBack(nums, tmp []int, ret [][]int, tk map[int]bool) [][]int {
// 递归出口
if len(nums) == len(tmp) {
c := make([]int, len(tmp))
copy(c, tmp)
// 4. ret[[3,6,9]]
ret = append(ret, c)
return ret
}
// [3, 6, 9]
for _, v := range nums {
// 回溯检查
if tk[v] {
continue
}
// 1. 做标记 tmp[3] map[3]=true
// 2. 做标记 tmp[3,6] map[6]=true
// 3. 做标记 tmp[3,6,9] map[9]=true
tmp = append(tmp, v)
tk[v] = true
ret = trackBack(nums, tmp, ret, tk)
// 清除
tk[v] = false
tmp = tmp[:len(tmp)-1]
}
return ret
}