Skip to content

Commit fc29731

Browse files
committed
feat: add solutions to lc problem: No.1638
No.1638.Count Substrings That Differ by One Character
1 parent 9538a31 commit fc29731

File tree

7 files changed

+332
-82
lines changed

7 files changed

+332
-82
lines changed

solution/1600-1699/1638.Count Substrings That Differ by One Character/README.md

Lines changed: 142 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,19 @@
7272

7373
**方法一:枚举**
7474

75-
枚举不同的那个字符,然后向两边扩展
75+
我们可以枚举字符串 $s$ 和 $t$ 中不同的那个字符位置,然后分别向两边扩展,直到遇到不同的字符为止,这样就可以得到以该位置为中心的满足条件的子串对数目。我们记左边扩展的相同字符个数为 $l$,右边扩展的相同字符个数为 $r$,那么以该位置为中心的满足条件的子串对数目为 $(l + 1) \times (r + 1)$,累加到答案中即可
7676

77-
时间复杂度 $O(m \times n \times min(m, n))$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是字符串 $s$ 和 $t$ 的长度。
77+
枚举结束后,即可得到答案。
78+
79+
时间复杂度 $O(m \times n \times \min(m, n))$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别为字符串 $s$ 和 $t$ 的长度。
80+
81+
**方法二:预处理 + 枚举**
82+
83+
方法一中,我们每次需要分别往左右两边扩展,得出 $l$ 和 $r$ 的值。实际上,我们可以预处理出以每个位置 $(i, j)$ 结尾的最长相同后缀的长度,以及以每个位置 $(i, j)$ 开头的最长相同前缀的长度,分别记录在数组 $f$ 和 $g$ 中。
84+
85+
接下来,与方法一类似,我们枚举字符串 $s$ 和 $t$ 中不同的那个字符位置 $(i, j)$,那么以该位置为中心的满足条件的子串对数目为 $(f[i][j] + 1) \times (g[i + 1][j + 1] + 1)$,累加到答案中即可。
86+
87+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为字符串 $s$ 和 $t$ 的长度。
7888

7989
<!-- tabs:start -->
8090

@@ -86,15 +96,36 @@
8696
class Solution:
8797
def countSubstrings(self, s: str, t: str) -> int:
8898
ans = 0
99+
m, n = len(s), len(t)
89100
for i, a in enumerate(s):
90101
for j, b in enumerate(t):
91102
if a != b:
92-
l = r = 1
93-
while i >= l and j >= l and s[i - l] == t[j - l]:
103+
l = r = 0
104+
while i > l and j > l and s[i - l - 1] == t[j - l - 1]:
94105
l += 1
95-
while i + r < len(s) and j + r < len(t) and s[i + r] == t[j + r]:
106+
while i + r + 1 < m and j + r + 1 < n and s[i + r + 1] == t[j + r + 1]:
96107
r += 1
97-
ans += l * r
108+
ans += (l + 1) * (r + 1)
109+
return ans
110+
```
111+
112+
```python
113+
class Solution:
114+
def countSubstrings(self, s: str, t: str) -> int:
115+
ans = 0
116+
m, n = len(s), len(t)
117+
f = [[0] * (n + 1) for _ in range(m + 1)]
118+
g = [[0] * (n + 1) for _ in range(m + 1)]
119+
for i, a in enumerate(s, 1):
120+
for j, b in enumerate(t, 1):
121+
if a == b:
122+
f[i][j] = f[i - 1][j - 1] + 1
123+
for i in range(m - 1, -1, -1):
124+
for j in range(n - 1, -1, -1):
125+
if s[i] == t[j]:
126+
g[i][j] = g[i + 1][j + 1] + 1
127+
else:
128+
ans += (f[i][j] + 1) * (g[i + 1][j + 1] + 1)
98129
return ans
99130
```
100131

@@ -105,19 +136,47 @@ class Solution:
105136
```java
106137
class Solution {
107138
public int countSubstrings(String s, String t) {
108-
int m = s.length(), n = t.length();
109139
int ans = 0;
140+
int m = s.length(), n = t.length();
110141
for (int i = 0; i < m; ++i) {
111142
for (int j = 0; j < n; ++j) {
112143
if (s.charAt(i) != t.charAt(j)) {
113-
int l = 1, r = 1;
114-
while (i - l >= 0 && j - l >= 0 && s.charAt(i - l) == t.charAt(j - l)) {
144+
int l = 0, r = 0;
145+
while (i - l > 0 && j - l > 0 && s.charAt(i - l - 1) == t.charAt(j - l - 1)) {
115146
++l;
116147
}
117-
while (i + r < m && j + r < n && s.charAt(i + r) == t.charAt(j + r)) {
148+
while (i + r + 1 < m && j + r + 1 < n && s.charAt(i + r + 1) == t.charAt(j + r + 1)) {
118149
++r;
119150
}
120-
ans += l * r;
151+
ans += (l + 1) * (r + 1);
152+
}
153+
}
154+
}
155+
return ans;
156+
}
157+
}
158+
```
159+
160+
```java
161+
class Solution {
162+
public int countSubstrings(String s, String t) {
163+
int ans = 0;
164+
int m = s.length(), n = t.length();
165+
int[][] f = new int[m + 1][n + 1];
166+
int[][] g = new int[m + 1][n + 1];
167+
for (int i = 0; i < m; ++i) {
168+
for (int j = 0; j < n; ++j) {
169+
if (s.charAt(i) == t.charAt(j)) {
170+
f[i + 1][j + 1] = f[i][j] + 1;
171+
}
172+
}
173+
}
174+
for (int i = m - 1; i >= 0; --i) {
175+
for (int j = n - 1; j >= 0; --j) {
176+
if (s.charAt(i) == t.charAt(j)) {
177+
g[i][j] = g[i + 1][j + 1] + 1;
178+
} else {
179+
ans += (f[i][j] + 1) * (g[i + 1][j + 1] + 1);
121180
}
122181
}
123182
}
@@ -132,21 +191,51 @@ class Solution {
132191
class Solution {
133192
public:
134193
int countSubstrings(string s, string t) {
194+
int ans = 0;
135195
int m = s.size(), n = t.size();
196+
for (int i = 0; i < m; ++i) {
197+
for (int j = 0; j < n; ++j) {
198+
if (s[i] != t[j]) {
199+
int l = 0, r = 0;
200+
while (i - l > 0 && j - l > 0 && s[i - l - 1] == t[j - l - 1]) {
201+
++l;
202+
}
203+
while (i + r + 1 < m && j + r + 1 < n && s[i + r + 1] == t[j + r + 1]) {
204+
++r;
205+
}
206+
ans += (l + 1) * (r + 1);
207+
}
208+
}
209+
}
210+
return ans;
211+
}
212+
};
213+
```
214+
215+
```cpp
216+
class Solution {
217+
public:
218+
int countSubstrings(string s, string t) {
136219
int ans = 0;
220+
int m = s.length(), n = t.length();
221+
int f[m + 1][n + 1];
222+
int g[m + 1][n + 1];
223+
memset(f, 0, sizeof(f));
224+
memset(g, 0, sizeof(g));
137225
for (int i = 0; i < m; ++i) {
138226
for (int j = 0; j < n; ++j) {
139227
if (s[i] == t[j]) {
140-
continue;
228+
f[i + 1][j + 1] = f[i][j] + 1;
141229
}
142-
int l = 1, r = 1;
143-
while (i - l >= 0 && j - l >= 0 && s[i - l] == t[j - l]) {
144-
++l;
145-
}
146-
while (i + r < m && j + r < n && s[i + r] == t[j + r]) {
147-
++r;
230+
}
231+
}
232+
for (int i = m - 1; i >= 0; --i) {
233+
for (int j = n - 1; j >= 0; --j) {
234+
if (s[i] == t[j]) {
235+
g[i][j] = g[i + 1][j + 1] + 1;
236+
} else {
237+
ans += (f[i][j] + 1) * (g[i + 1][j + 1] + 1);
148238
}
149-
ans += l * r;
150239
}
151240
}
152241
return ans;
@@ -158,17 +247,47 @@ public:
158247

159248
```go
160249
func countSubstrings(s string, t string) (ans int) {
250+
m, n := len(s), len(t)
161251
for i, a := range s {
162252
for j, b := range t {
163253
if a != b {
164-
l, r := 1, 1
165-
for i >= l && j >= l && s[i-l] == t[j-l] {
254+
l, r := 0, 0
255+
for i > l && j > l && s[i-l-1] == t[j-l-1] {
166256
l++
167257
}
168-
for i+r < len(s) && j+r < len(t) && s[i+r] == t[j+r] {
258+
for i+r+1 < m && j+r+1 < n && s[i+r+1] == t[j+r+1] {
169259
r++
170260
}
171-
ans += l * r
261+
ans += (l + 1) * (r + 1)
262+
}
263+
}
264+
}
265+
return
266+
}
267+
```
268+
269+
```go
270+
func countSubstrings(s string, t string) (ans int) {
271+
m, n := len(s), len(t)
272+
f := make([][]int, m+1)
273+
g := make([][]int, m+1)
274+
for i := range f {
275+
f[i] = make([]int, n+1)
276+
g[i] = make([]int, n+1)
277+
}
278+
for i, a := range s {
279+
for j, b := range t {
280+
if a == b {
281+
f[i+1][j+1] = f[i][j] + 1
282+
}
283+
}
284+
}
285+
for i := m - 1; i >= 0; i-- {
286+
for j := n - 1; j >= 0; j-- {
287+
if s[i] == t[j] {
288+
g[i][j] = g[i+1][j+1] + 1
289+
} else {
290+
ans += (f[i][j] + 1) * (g[i+1][j+1] + 1)
172291
}
173292
}
174293
}

0 commit comments

Comments
 (0)