LC.P1638[统计只差一个字符的子串数目]

题目描述

给你两个字符串 st ,请你找出 s 中的非空子串的数目,这些子串满足替换 一个不同字符 以后,是 t 串的子串。换言之,请你找到 st 串中 恰好 只有一个字符不同的子字符串对的数目。

比方说, "computer" and "computation" 只有一个字符不同: 'e'/'a' ,所以这一对子字符串会给答案加 1 。

请你返回满足上述条件的不同子字符串对数目。

一个 子字符串 是一个字符串中连续的字符。

示例1

输入:s = “aba”, t = “baba”
输出:6
解释:以下为只相差 1 个字符的 s 和 t 串的子字符串对:
(“aba”, “baba”)
(“aba”, “baba”)
(“aba”, “baba”)
(“aba”, “baba”)
(“aba”, “baba”)
(“aba”, “baba”)
加粗部分分别表示 s 和 t 串选出来的子字符串。

示例2

输入:s = “ab”, t = “bb”
输出:3
解释:以下为只相差 1 个字符的 s 和 t 串的子字符串对:
(“ab”, “bb”)
(“ab”, “bb”)
(“ab”, “bb”)
加粗部分分别表示 s 和 t 串选出来的子字符串。

示例3

输入:s = “a”, t = “a”
输出:0

提示:

  • 1 <= s.length, t.length <= 100
  • st 都只包含小写英文字母。

方法一:暴力枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int countSubstrings(String s, String t) {
int m = s.length(), n = t.length(), ans = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (s.charAt(i) != t.charAt(j)) {
int l = 0, r = 0;
while (i - l > 0 && j - l > 0 && s.charAt(i - l - 1) == t.charAt(j - l - 1)) ++l;
while (i + r + 1 < m && j + r + 1 < n && s.charAt(i + r + 1) == t.charAt(j + r + 1)) ++r;
ans += (l + 1) * (r + 1);
}
}
}
return ans;
}
}
  • 时间复杂度:$O(m×n×min(m,n))$
  • 空间复杂度:$O(1)$

方法二:非暴力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int countSubstrings(String s, String t) {
int ans = 0, n = s.length(), m = t.length();
for (int d = 1 - m; d < n; ++d) {
int i = Math.max(d, 0);
for (int k0 = i - 1, k1 = k0; i < n && i - d < m; ++i) {
if (s.charAt(i) != t.charAt(i - d)) {
k0 = k1;
k1 = i;
}
ans += k1 - k0;
}
}
return ans;
}
}
  • 时间复杂度:$O(m×n)$
  • 空间复杂度:$O(1)$