算法训练营day23(补),回溯3
import (
"sort"
)
39. 组合总和
func combinationSum(candidates []int, target int) [][]int {
//存储全部集合
result := make([][]int, 0)
if len(candidates) == 0 {
return result
}
sort.Ints(candidates) //排序后面做剪枝
//存储单次集合
path := make([]int, 0)
var backtrace func(candidates []int, target int, startIndex int)
backtrace = func(candidates []int, target int, startIndex int) {
if target == 0 {
temp := make([]int, len(path))
copy(temp, path)
result = append(result, temp)
return
}
for i := startIndex; i < len(candidates); i++ {
if candidates[i] > target { //剪枝
break
}
path = append(path, candidates[i])
backtrace(candidates, target-candidates[i], i)
//回溯处理
path = path[:len(path)-1]
}
}
backtrace(candidates, target, 0)
return result
}
40. 组合总和 II
func combinationSum2(candidates []int, target int) [][]int {
//存储全部集合
result := make([][]int, 0)
if len(candidates) == 0 {
return result
}
sort.Ints(candidates) //排序后面做剪枝
//记录数组每一个元素是否使用过
user := make([]bool, len(candidates))
//存储单次集合
path := make([]int, 0)
var backtrace func(candidates []int, target int, startIndex int)
backtrace = func(candidates []int, target int, startIndex int) {
if target == 0 {
temp := make([]int, len(path))
copy(temp, path)
result = append(result, temp)
return
}
for i := startIndex; i < len(candidates); i++ {
if candidates[i] > target { //剪枝
break
}
if i > 0 && candidates[i] == candidates[i-1] && user[i-1] == false { //过滤重复
continue
}
path = append(path, candidates[i])
user[i] = true
backtrace(candidates, target-candidates[i], i+1)
//回溯处理
path = path[:len(path)-1]
user[i] = false
}
}
backtrace(candidates, target, 0)
return result
}
//判断是否是回文
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
}
131. 分割回文串
func partition(s string) [][]string {
//存储全部集合
result := make([][]string, 0)
if len(s) == 0 {
return result
}
//存储单次集合
path := make([]string, 0)
var backtrace func(se string, startIndex int)
backtrace = func(se string, startIndex int) {
if startIndex == len(se) {
temp := make([]string, len(path))
copy(temp, path)
result = append(result, temp)
return
}
for i := startIndex; i < len(se); i++ {
//对字符串进行切割
str := se[startIndex : i+1]
if isPalindrome(str) {
path = append(path, str)
backtrace(se, i+1)
//回溯处理
path = path[:len(path)-1]
}
}
}
backtrace(s, 0)
return result
}