Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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)

AltStyle によって変換されたページ (->オリジナル) /