题目:
给你两个字符串 s 和 t ,请你找出 s 中的非空子串的数目,这些子串满足替换 一个不同字符 以后,是 t 串的子串。换言之,请你找到 s 和 t 串中 恰好 只有一个字符不同的子字符串对的数目。
比方说, "computer" and "computation" 只有一个字符不同: 'e'/'a' ,所以这一对子字符串会给答案加 1 。
请你返回满足上述条件的不同子字符串对数目。
一个 子字符串 是一个字符串中连续的字符。
算法:
方法一:暴力
func countSubstrings(s string, t string) int {
count := 0
for end := 1; end <= len(t); end ++ {
for length := 1; length <= end; length ++ {
tStr := string(t[end - length:end])
for i := 0; i + length <= len(s); i ++ {
sStr := string(s[i:i + length])
if sStr == tStr {
continue
}
distinctCharCount := 0
for k := 0; k < len(sStr); k ++ {
if sStr[k] != tStr[k] {
distinctCharCount ++
}
if distinctCharCount > 1 {
break
}
}
if distinctCharCount == 1 {
count ++
}
}
}
}
return count
}
方法二:优化 方法一的时间复杂度O(mnMin(m,n)),空间复杂度O(1) 优化后时间复杂度O(mn),空间复杂度O(mn)
func countSubstrings(s string, t string) int {
count := 0
m, n := len(s), len(t)
// f[i][j] s,t以i,j为最后一个元素的“只差一个字符的子串”数目
f := make([][]int, m + 1)
// g[i][j] s,t以i,j为最后一个元素的相等子串的数目
g := make([][]int, m + 1)
for i := range f {
f[i] = make([]int, n + 1)
g[i] = make([]int, n + 1)
}
for i := 0; i < m; i ++ {
for j := 0; j < n; j ++ {
if s[i] == t[j] {
g[i + 1][j + 1] = g[i][j] + 1
f[i + 1][j + 1] = f[i][j]
} else {
g[i + 1][j + 1] = 0
f[i + 1][j + 1] = g[i][j] + 1
}
count = count + f[i + 1][j + 1]
}
}
return count
}