// 04 39. 组合总和
package main
import (
"fmt"
"sort"
)
func combinationSum(candidates []int, target int) [][]int {
// 全局变量
res := [][]int{}
path := []int{}
sort.Ints(candidates) //输入数组排序
//回溯函数
var backtracking func(candidates []int, target, sum, startindex int)
backtracking = func(candidates []int, target, sum, startindex int) {
//终止条件
if sum > target {
return
}
if sum == target {
temp := make([]int, len(path))
copy(temp, path)
res = append(res, temp)
return
}
//for循环遍历每个结点
for i := startindex; i < len(candidates); i++ {
if candidates[i] > target { //剪枝
continue //若当前遍历到的结点大于目标值,开始下一个结点的遍历
}
path = append(path, candidates[i])
sum += candidates[i]
backtracking(candidates, target, sum, i) //回溯,元素可以重复取,startindex为i
path = path[:len(path)-1]
sum -= candidates[i]
}
return
}
backtracking(candidates, target, 0, 0)
return res
}
func main() {
candidates := []int{2, 3, 6, 7}
res := combinationSum(candidates, 7)
fmt.Printf("res: %v\n", res) //res: [[2 2 3] [7]]
}
// 05 40.组合总和II
package main
import (
"fmt"
"sort"
)
func combinationSum2(candidates []int, target int) [][]int {
// 全局变量
path := make([]int, 0)
res := make([][]int, 0)
used := make([]bool, len(candidates))//注意预分配大小
sort.Ints(candidates) //排序
//回溯函数
var dfs func(candidates []int, target, sum, startindex int, used []bool)
dfs = func(candidates []int, target, sum, startindex int, used []bool) {
//终止条件
if sum > target {
return
}
if target == sum {
temp := make([]int, len(path))
copy(temp, path)
res = append(res, temp)
return
}
//for循环遍历每个结点,注意剪枝
for i := startindex; i < len(candidates); i++ {
if candidates[i] > target {
break
}
if i != 0 && candidates[i] == candidates[i-1] && used[i-1] == false { //剪枝
continue
}
path = append(path, candidates[i])
sum += candidates[i]
used[i] = true
dfs(candidates, target, sum, i+1, used)
path = path[:len(path)-1]
sum -= candidates[i]
used[i] = false
}
return
}
dfs(candidates, target, 0, 0, used)
return res
}
func main() {
candidates := []int{10, 1, 2, 7, 6, 1, 5}
res := combinationSum2(candidates, 8)
fmt.Printf("res: %v\n", res) //res: [[1 1 6] [1 2 5] [1 7] [2 6]]
}
// 06 131.分割回文串
package main
import "fmt"
func partition(s string) [][]string {
// 全局变量
path := []string{}
res := [][]string{}
// 回溯函数
var dfs func(s string, startindex int)
dfs = func(s string, startindex int) {
//终止条件
if startindex >= len(s) {
temp := make([]string, len(path))
copy(temp, path)
res = append(res, temp)
return
}
//for循环遍历所有结点
for i := startindex; i < len(s); i++ {
str := s[startindex : i+1]
if isPalindrome(str) == true { //判断是否为回文
path = append(path, str) //是回文串加入结果集
dfs(s, i+1) //回溯
path = path[:len(path)-1]
}
}
return
}
dfs(s, 0)
return res
}
func isPalindrome(s string) bool { //判断是否为回文串
left := 0
right := len(s) - 1
for left < right {
if s[left] != s[right] {
return false
}
left++
right--
}
return true
}
func main() {
s := "aab"
res := partition(s)
fmt.Printf("res: %v\n", res) //res: [[a a b] [aa b]]
}