Skip to content

Commit 1bfb863

Browse files
committed
feat: add solutions to lcof2/lc problem: Palindromic Substrings
1 parent 1547a6b commit 1bfb863

File tree

7 files changed

+209
-6
lines changed

7 files changed

+209
-6
lines changed

lcof2/剑指 Offer II 020. 回文子字符串的个数/README.md

+43-2
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,63 @@
4343

4444
<!-- 这里可写通用的实现逻辑 -->
4545

46+
在 Manacher 算法的计算过程中,`p[i] - 1` 表示以第 `i` 位为中心的最大回文长度,`(p[i] - 1) / 2` **向上取整**即可得到以第 `i` 位为中心的回文串数量
47+
4648
<!-- tabs:start -->
4749

4850
### **Python3**
4951

5052
<!-- 这里可写当前语言的特殊实现逻辑 -->
5153

5254
```python
53-
55+
class Solution:
56+
def countSubstrings(self, s: str) -> int:
57+
t = '^#' + '#'.join(s) + '#$'
58+
n = len(t)
59+
p = [0 for _ in range(n)]
60+
pos, maxRight = 0, 0
61+
ans = 0
62+
for i in range(1, n - 1):
63+
p[i] = min(maxRight - i, p[2 * pos - i]) if maxRight > i else 1
64+
while t[i - p[i]] == t[i + p[i]]:
65+
p[i] += 1
66+
if i + p[i] > maxRight:
67+
maxRight = i + p[i]
68+
pos = i
69+
ans += p[i] // 2
70+
return ans
5471
```
5572

5673
### **Java**
5774

5875
<!-- 这里可写当前语言的特殊实现逻辑 -->
5976

6077
```java
61-
78+
class Solution {
79+
public int countSubstrings(String s) {
80+
StringBuilder sb = new StringBuilder("^#");
81+
for (char ch : s.toCharArray()) {
82+
sb.append(ch).append('#');
83+
}
84+
String t = sb.append('$').toString();
85+
int n = t.length();
86+
int[] p = new int[n];
87+
int pos = 0, maxRight = 0;
88+
int ans = 0;
89+
for (int i = 1; i < n - 1; i++) {
90+
p[i] = maxRight > i ? Math.min(maxRight - i, p[2 * pos - i]) : 1;
91+
while (t.charAt(i - p[i]) == t.charAt(i + p[i])) {
92+
p[i]++;
93+
}
94+
if (i + p[i] > maxRight) {
95+
maxRight = i + p[i];
96+
pos = i;
97+
}
98+
ans += p[i] / 2;
99+
}
100+
return ans;
101+
}
102+
}
62103
```
63104

64105
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
public int countSubstrings(String s) {
3+
StringBuilder sb = new StringBuilder("^#");
4+
for (char ch : s.toCharArray()) {
5+
sb.append(ch).append('#');
6+
}
7+
String t = sb.append('$').toString();
8+
int n = t.length();
9+
int[] p = new int[n];
10+
int pos = 0, maxRight = 0;
11+
int ans = 0;
12+
for (int i = 1; i < n - 1; i++) {
13+
p[i] = maxRight > i ? Math.min(maxRight - i, p[2 * pos - i]) : 1;
14+
while (t.charAt(i - p[i]) == t.charAt(i + p[i])) {
15+
p[i]++;
16+
}
17+
if (i + p[i] > maxRight) {
18+
maxRight = i + p[i];
19+
pos = i;
20+
}
21+
ans += p[i] / 2;
22+
}
23+
return ans;
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def countSubstrings(self, s: str) -> int:
3+
t = '^#' + '#'.join(s) + '#$'
4+
n = len(t)
5+
p = [0 for _ in range(n)]
6+
pos, maxRight = 0, 0
7+
ans = 0
8+
for i in range(1, n - 1):
9+
p[i] = min(maxRight - i, p[2 * pos - i]) if maxRight > i else 1
10+
while t[i - p[i]] == t[i + p[i]]:
11+
p[i] += 1
12+
if i + p[i] > maxRight:
13+
maxRight = i + p[i]
14+
pos = i
15+
ans += p[i] // 2
16+
return ans

solution/0600-0699/0647.Palindromic Substrings/README.md

+43-2
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,63 @@
3838

3939
<!-- 这里可写通用的实现逻辑 -->
4040

41+
在 Manacher 算法的计算过程中,`p[i] - 1` 表示以第 `i` 位为中心的最大回文长度,`(p[i] - 1) / 2` **向上取整**即可得到以第 `i` 位为中心的回文串数量
42+
4143
<!-- tabs:start -->
4244

4345
### **Python3**
4446

4547
<!-- 这里可写当前语言的特殊实现逻辑 -->
4648

4749
```python
48-
50+
class Solution:
51+
def countSubstrings(self, s: str) -> int:
52+
t = '^#' + '#'.join(s) + '#$'
53+
n = len(t)
54+
p = [0 for _ in range(n)]
55+
pos, maxRight = 0, 0
56+
ans = 0
57+
for i in range(1, n - 1):
58+
p[i] = min(maxRight - i, p[2 * pos - i]) if maxRight > i else 1
59+
while t[i - p[i]] == t[i + p[i]]:
60+
p[i] += 1
61+
if i + p[i] > maxRight:
62+
maxRight = i + p[i]
63+
pos = i
64+
ans += p[i] // 2
65+
return ans
4966
```
5067

5168
### **Java**
5269

5370
<!-- 这里可写当前语言的特殊实现逻辑 -->
5471

5572
```java
56-
73+
class Solution {
74+
public int countSubstrings(String s) {
75+
StringBuilder sb = new StringBuilder("^#");
76+
for (char ch : s.toCharArray()) {
77+
sb.append(ch).append('#');
78+
}
79+
String t = sb.append('$').toString();
80+
int n = t.length();
81+
int[] p = new int[n];
82+
int pos = 0, maxRight = 0;
83+
int ans = 0;
84+
for (int i = 1; i < n - 1; i++) {
85+
p[i] = maxRight > i ? Math.min(maxRight - i, p[2 * pos - i]) : 1;
86+
while (t.charAt(i - p[i]) == t.charAt(i + p[i])) {
87+
p[i]++;
88+
}
89+
if (i + p[i] > maxRight) {
90+
maxRight = i + p[i];
91+
pos = i;
92+
}
93+
ans += p[i] / 2;
94+
}
95+
return ans;
96+
}
97+
}
5798
```
5899

59100
### **...**

solution/0600-0699/0647.Palindromic Substrings/README_EN.md

+41-2
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,52 @@
7171
### **Python3**
7272

7373
```python
74-
74+
class Solution:
75+
def countSubstrings(self, s: str) -> int:
76+
t = '^#' + '#'.join(s) + '#$'
77+
n = len(t)
78+
p = [0 for _ in range(n)]
79+
pos, maxRight = 0, 0
80+
ans = 0
81+
for i in range(1, n - 1):
82+
p[i] = min(maxRight - i, p[2 * pos - i]) if maxRight > i else 1
83+
while t[i - p[i]] == t[i + p[i]]:
84+
p[i] += 1
85+
if i + p[i] > maxRight:
86+
maxRight = i + p[i]
87+
pos = i
88+
ans += p[i] // 2
89+
return ans
7590
```
7691

7792
### **Java**
7893

7994
```java
80-
95+
class Solution {
96+
public int countSubstrings(String s) {
97+
StringBuilder sb = new StringBuilder("^#");
98+
for (char ch : s.toCharArray()) {
99+
sb.append(ch).append('#');
100+
}
101+
String t = sb.append('$').toString();
102+
int n = t.length();
103+
int[] p = new int[n];
104+
int pos = 0, maxRight = 0;
105+
int ans = 0;
106+
for (int i = 1; i < n - 1; i++) {
107+
p[i] = maxRight > i ? Math.min(maxRight - i, p[2 * pos - i]) : 1;
108+
while (t.charAt(i - p[i]) == t.charAt(i + p[i])) {
109+
p[i]++;
110+
}
111+
if (i + p[i] > maxRight) {
112+
maxRight = i + p[i];
113+
pos = i;
114+
}
115+
ans += p[i] / 2;
116+
}
117+
return ans;
118+
}
119+
}
81120
```
82121

83122
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
public int countSubstrings(String s) {
3+
StringBuilder sb = new StringBuilder("^#");
4+
for (char ch : s.toCharArray()) {
5+
sb.append(ch).append('#');
6+
}
7+
String t = sb.append('$').toString();
8+
int n = t.length();
9+
int[] p = new int[n];
10+
int pos = 0, maxRight = 0;
11+
int ans = 0;
12+
for (int i = 1; i < n - 1; i++) {
13+
p[i] = maxRight > i ? Math.min(maxRight - i, p[2 * pos - i]) : 1;
14+
while (t.charAt(i - p[i]) == t.charAt(i + p[i])) {
15+
p[i]++;
16+
}
17+
if (i + p[i] > maxRight) {
18+
maxRight = i + p[i];
19+
pos = i;
20+
}
21+
ans += p[i] / 2;
22+
}
23+
return ans;
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def countSubstrings(self, s: str) -> int:
3+
t = '^#' + '#'.join(s) + '#$'
4+
n = len(t)
5+
p = [0 for _ in range(n)]
6+
pos, maxRight = 0, 0
7+
ans = 0
8+
for i in range(1, n - 1):
9+
p[i] = min(maxRight - i, p[2 * pos - i]) if maxRight > i else 1
10+
while t[i - p[i]] == t[i + p[i]]:
11+
p[i] += 1
12+
if i + p[i] > maxRight:
13+
maxRight = i + p[i]
14+
pos = i
15+
ans += p[i] // 2
16+
return ans

0 commit comments

Comments
 (0)