对数组排序,方便剪枝;剪枝:当前path求和大于target进行下一轮循环
数组中元素可以重复取值,所以递归时可以取当前值
func combinationSum(candidates []int, target int) [][]int {
res := [][]int{}
path := []int{}
sort.Ints(candidates)
var help func(candidates []int, target, sum, startIndex int)
help = func(candidates []int, target, sum, startIndex int) {
if sum == target {
tmp := make([]int, len(path))
copy(tmp, path)
res = append(res, tmp)
return
}
for i := startIndex; i < len(candidates) && sum+candidates[i] <= target; i++ {
sum += candidates[i]
path = append(path, candidates[i])
help(candidates, target, sum, i)
sum -= candidates[i]
path = path[:len(path)-1]
}
}
help(candidates, target, 0, 0)
return res
}
数组中有重复元素,要求结果集合不能重复
注意:去重同一层元素,used[i - 1] = false,说明是从前一个元素回溯回来的,若used[i - 1] = true说明是进入下一个递归取值
func combinationSum2(candidates []int, target int) [][]int {
res := [][]int{}
path := []int{}
used := make([]bool, len(candidates))
sort.Ints(candidates)
var help func(candidates []int, target, sum, startIndex int)
help = func(candidates []int, target, sum, startIndex int) {
if sum == target {
tmp := make([]int, len(path))
copy(tmp, path)
res = append(res, tmp)
return
}
for i := startIndex; i < len(candidates) && sum+candidates[i] <= target; i++ {
if i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false {
continue
}
sum += candidates[i]
used[i] = true
path = append(path, candidates[i])
help(candidates, target, sum, i+1)
path = path[:len(path)-1]
used[i] = false
sum -= candidates[i]
}
}
help(candidates, target, 0, 0)
return res
}
当切割点在string长度位置,说明找到一组符合要求的结果
如果是回文串,递归寻找后面的回文串,回溯;否则跳过当前元素
func partition(s string) [][]string {
res := [][]string{}
path := []string{}
var help func(s string, startIndex int)
help = func(s string, startIndex int) {
if startIndex == len(s) {
tmp := make([]string, len(path))
copy(tmp, path)
res = append(res, tmp)
return
}
for i := startIndex; i < len(s); i++ {
str := s[startIndex : i+1]
if isPalindrome(str) {
path = append(path, str)
help(s, i+1)
path = path[:len(path)-1]
}
}
}
help(s, 0)
return res
}
func isPalindrome(s string) bool {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
if s[i] != s[j] {
return false
}
}
return true
}
39.组合总和
40.组合总和II
131.分割回文串
组合、切割、子集、排列、棋盘:N皇后,解数独等等
学习go语言map实现set
基本能实现回溯,代码随想录yyds