647. 回文子串
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindromic-substrings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
中心拓展
class Solution {
private int count(String s, int l, int r) {
int ans = 0;
while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
--l;
++r;
ans++;
}
return ans;
}
public int countSubstrings(String s) {
int n = s.length(), ans = 0;
for (int i = 0; i < n; ++i) {
ans += count(s, i, i);
ans += count(s, i, i + 1);
}
return ans;
}
}
Manacher
import java.util.Scanner;
class Solution {
private char[] getManacher(String s) {
char[] res = new char[s.length() * 2 + 1];
for (int i = 0; i < s.length(); ++i) {
res[i * 2] = '#';
res[i * 2 + 1] = s.charAt(i);
}
res[res.length - 1] = '#';
return res;
}
public int countSubstrings(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] manacher = getManacher(s);
int ret = 0;
int r = -1, c = 0;
int[] p = new int[manacher.length];
for (int i = 0; i < manacher.length; ++i) {
p[i] = i > r ? 1 : Math.min(p[2 * c - i], r - i + 1);
while (i + p[i] < manacher.length && i - p[i] >= 0 && manacher[i + p[i]] == manacher[i - p[i]]) {
p[i]++;
}
ret += p[i] / 2;
if (i + p[i] - 1 > r) {
r = i + p[i] - 1;
c = i;
}
}
return ret;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
System.out.println(new Solution().countSubstrings(in.next()));
}
}
}
心之所向,素履以往 生如逆旅,一苇以航

浙公网安备 33010602011771号