17 阅读1分钟

# 1. 字符串匹配（KMP）

## 1.1 重复的子字符串

• KMP算法详解

KMP 算法详解 - 知乎 (zhihu.com)

• 解法
``````class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s.equals("")) return false;

int m = s.length();

// 将两个s拼接在一起,并且去掉首尾字符
String txt = s + s;
txt = txt.substring(1, 2*m-1);

int n = 2*m - 2;

// kmp算法,找中间是否出现s
int[][] dp = new int[m][256];
dp[0][s.charAt(0)] = 1;
int X = 0;
for(int j=1;j<m;j++){
for(int c='a';c<'z';c++) dp[j][c] = dp[X][c];

dp[j][s.charAt(j)] = j+1;
X = dp[X][s.charAt(j)];
}

int j = 0;
for(int i=0;i<n;i++){
j = dp[j][txt.charAt(i)];
if(j == m) return true;
}

return false;
}
}
``````

# 2. 回文子串

## 2.1 回文子串

``````class Solution {
public int countSubstrings(String s) {
// 中心扩展法
int n = s.length();
int ans = n; // 默认一个字符的均为回文串

// 以一个字符为中心
for(int i=0;i<n;i++){
int left = i-1;
int right = i+1;
while(left>=0 && right<n && s.charAt(left)==s.charAt(right)){
left--;
right++;
ans++;
}
}

// 以两个字符为中心
for(int i=0;i<n-1;i++){
if(s.charAt(i) == s.charAt(i+1)){
ans++;
int left = i-1;
int right = i+2;
while(left>=0 && right<n && s.charAt(left) == s.charAt(right)){
ans++;
left--;
right++;
}
}
}

return ans;
}
}
``````

## 2.2 最长回文子串

``````class Solution {
public String longestPalindrome(String s) {
// 中心扩展法
int n = s.length();
int maxn = -1;   // 最长长度
String ans = ""; // 答案

for(int center=0;center<2*n-1;center++){
int left = center/2;
int right = left + center%2;
while(left>=0 && right<n && s.charAt(left)==s.charAt(right)){
String tmp = s.substring(left, right+1);
if(tmp.length() > ans.length()) ans = tmp;

left--;
right++;
}
}

return ans;
}
}
``````