解法一:回溯
从 s 的头部开始暴力穷举,如果发现 s[0..i] 是一个回文子串,那么我们就可以把 s 切分为 s[0..i] 和 s[i+1..],然后递归尝试再把 s[i+1..] 切分成多个回文子串即可。
决策树如下,树枝上是每次从头部穷举切分出的子串,节点上是待切分的剩余字符串
func partition(s string) [][]string {
var res [][]string
path := make([]string, 0)
backtrack(s, 0, path, &res)
return res
}
func backtrack(s string, offset int, path []string, res *[][]string){
if offset == len(s){ // base case
// 整个 s 被成功分割为若干个回文子串,更新答案
tmp := make([]string, len(path))
copy(tmp, path)
*res = append(*res, tmp)
return
}
for i:=offset; i<len(s); i++{
subStr := s[offset:i+1]
if isValid(subStr){
// s[offset:i+1]是一个回文串,可以进行分割
// 做选择,把该回文串加入路径列表中
path = append(path, subStr)
// 继续在下一层递归中,在s[offset+1:]中尝试分割出回文串
backtrack(s, i+1, path, res)
// 撤销选择
path = path[:len(path)-1]
}
}
}
func isValid(s string) bool{
left, right := 0, len(s)-1
for left < right{
if s[left] != s[right]{
return false
}
left++
right--
}
return true
}