题目:
算法:
方法一:模拟+回溯
执行会超时
func findSubstringInWraproundString(p string) int {
subStr := make(map[string]struct{})
// 长度为1,
// 大于一,
n := len(p)
list := make([]byte, 0)
var dfs func(i int)
dfs = func(i int) {
if i == n {
return
}
dfs(i + 1)
// 是否可以组成有效子串
if len(list) > 0 {
last := list[len(list) - 1]
if last + 1 != p[i] && p[i] + 25 != last {
// fmt.Println(string(last), string(p[i]))
return
}
}
list = append(list, p[i])
subStr[string(list)] = struct{}{}
dfs(i + 1)
list = list[:len(list) - 1]
}
dfs(0)
// fmt.Println(subStr)
return len(subStr)
}
方法二:动态规划
dp[i] 表示以 p[i]为最后一个元素的子串长度。
如p="abc”,p[2] = 3, 三个子串分别是,"abc","bc","b"
最终结果为所有dp元素之和。
因为有了结尾元素p[i],和长度dp[i],我们可以据此去重
如dp['c']存在两个子串“abc”和“bc”,取最大值作为dp[i]的值即可实现去重
func findSubstringInWraproundString(p string) int {
dp := make([]int, 26)
k := 0
for i := range p {
if i > 0 && (p[i - 1] + 1 == p[i] || p[i] + 25 == p[i - 1]) {
k ++
} else {
k = 1
}
dp[p[i] - 'a'] = max(dp[p[i] - 'a'], k)
}
ans := 0
for i := range dp {
ans = ans + dp[i]
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}