1638. 统计只差一个字符的子串数目

94 阅读1分钟

题目:
给你两个字符串 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
}