回溯问题
回溯通常用来解决这些问题
组合问题:N个数里面按一定规则找出k个数的集合
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
排列问题:N个数按一定规则全排列,有几种排列方式
棋盘问题:N皇后,解数独等等
77组合
func combine(n int, k int) [][]int {// 回溯加剪枝var path = []int{}var res = [][]int{}backtracking(n, k, 1, &path, &res)return res
}func backtracking(n, k, startidx int, path *[]int, res *[][]int) {if len(*path) == k {newpath := make([]int, len(*path)) // !!!易错点,此处必须要将path重新赋值给新的变量,不然直接*res = append(*res, *path) 这样传递的是path的引用,导致最终所有结果都一样copy(newpath, *path)*res = append(*res, newpath)return}// 剪枝if n-startidx+1 < k - len(*path) { // 易错点2,剪枝操作,如果剩余元素小于目标长度减去路径列表已有长度才剪枝,而不是直接判断index 与 k的关系return}for i:=startidx; i<=n; i++ {*path = append(*path, i) // 添加元素backtracking(n, k, i+1, path, res)*path = (*path)[:len(*path) - 1] // 回溯删除上面添加的元素}return
}
216 排列之和
//leetcode submit region begin(Prohibit modification and deletion)
func combinationSum3(k int, n int) [][]int {// 思路组合问题另一种变体,返回值res用来存放和满足条件的结果即可var path = []int{}var res = [][]int{}backtracking(k, n, 1, &path, &res)return res
}func backtracking(k, n, startidx int, path *[]int, res *[][]int) {length := len(*path)if sum(*path) == n && length == k{var copypath = make([]int, length)copy(copypath, *path)*res = append(*res, copypath)return}// 剪枝操作,如果当前剩余数组长度小于目标长度减去已有长度,剪枝if 9 - startidx + 1 < k - length {return}// 剪枝2,最小和、大于目标和if minsum(k) > n {return}// 回溯递归for i:=startidx; i<=9; i++{*path = append(*path, i)backtracking(k, n, i+1, path, res)*path = (*path)[0 : len(*path) - 1]}return
}func sum(li []int) int {var sum intfor _, i := range li {sum += i}return sum
}func minsum (k int) int {// 返回1-9 k个数最小和var sum intfor i:=1; i<=k; i++{sum += i}return sum
}
17 电话号码对应字母组合
func letterCombinations(digits string) []string {if len(digits) == 0 {return nil}var path = []string{}var res = []string{}backtracking(0, digits, &path, &res)return res
}func backtracking(stridx int, k string, path *[]string, res *[]string){if len(*path) == len(k) {str := strings.Join(*path, "")*res = append(*res, str)return}// 剪枝情况, 结果集要的是全部情况,应该不能剪枝key, _ := strconv.Atoi(string(k[stridx]))for _, v := range digmap[key] { // var v rune == var v []int32*path = append(*path, string(v))backtracking(stridx+1, k, path, res)*path = (*path)[0 : len(*path) - 1]}return
}