今日题目:
39. 组合总和
40. 组合总和 II
131.分割回文串
今日总结
在组合问题中要特别注意start下标的选择,这里第二题还涉及到了去重。第三题看看是怎么进行分割的,和组合问题的区别。
39. 组合总和
要点
- 由于元素可以重复使用,所以这里的start不用在递归时加一
代码:
var (
path []int
res [][]int
)
func combinationSum(candidates []int, target int) [][]int {
path, res = make([]int, 0), make([][]int, 0)
dfs(candidates, target, 0)
return res
}
func dfs(candidates []int, target int, start int){
if sum(path) == target{
tmp := make([]int, len(path))
copy(tmp, path)
res = append(res, tmp)
return
}
for i := start; i < len(candidates); i++ {
if sum(path) > target{
return
}
path = append(path, candidates[i])
dfs(candidates, target, i) // 注意这里使用了 'i'
path = path[:len(path)-1]
}
}
func sum(list []int) int {
res := 0
for _,item := range list{
res += item
}
return res
}
40. 组合总和 II
要点:
- 与前一题的区别在于去重
- 去重比较讨巧,先使用排序使相同元素相邻,然后再判断是否相同即可
var (
path []int
res [][]int
)
func combinationSum2(candidates []int, target int) [][]int {
sort.Ints(candidates)
path, res = make([]int, 0), make([][]int, 0)
dfs(candidates, target, 0)
return res
}
func dfs(candidates []int, target int, start int) {
if sum(path) == target {
tmp := make([]int, len(path))
copy(tmp, path)
res = append(res, tmp)
return
}
for i := start; i < len(candidates); i++{
if i > start && candidates[i] == candidates[i-1] {
continue
}
if sum(path) > target {
break
}
path = append(path, candidates[i])
dfs(candidates, target, i+1)
path = path[:len(path)-1]
}
}
func sum(a []int) int{
res := 0
for _,item := range a{
res += item
}
return res
}
131.分割回文串
要点:
- 要注意这一题分割的方法,使用start和i来划定字符串范围
- 再树形结构上,每一层递归就意味着在字符串上切一刀
var (
path []string
res [][]string
)
func partition(s string) [][]string {
path, res = make([]string, 0), make([][]string, 0)
dfs(s, 0)
return res
}
func dfs(s string, start int) {
if start == len(s) {
tmp := make([]string, len(path)) //注意这里如果是len(s)会把空串也当作回文的 因为s长度肯定大于path 会有空元素
copy(tmp, path)
res = append(res, tmp)
return
}
for i:=start; i<len(s); i++{
if isHuiWen(s[start:i+1]){
path = append(path, s[start:i+1])
dfs(s, i+1)
path = path[:len(path)-1]
}
}
}
func isHuiWen(s string) bool {
for i:=0; i <len(s)/2; i++{
if s[i] != s[len(s)-i-1]{
return false
}
}
return true
}