题目描述
就是数子串中有多少是回文串
解法
迭代,一开始我是自底向上:也就是按字符串长度1,2,3,…,len,如果字符串是回文串,就横向扩展,也就是说如果a[left-1] == a[right+1],就知道相邻的子串也是回文串。最终这种方法超时了。然后换成自顶向下:也就是从len,len-1,len-2,…,1,如果一个子串是回文串,那么这个子串的多个子串也都是回文子串。
class Solution {
public int countSubstrings(String s) {
int len = s.length();
boolean[][] mark = new boolean[len][len];
int res = 0;
// for (int l = 1; l <= len; l++) {
// for (int i = 0; i <= len - l; i++) {
// int j = i + l - 1;
// if (mark[i][j]) {
// res++;
// continue;
// }
// if (i == j) {
// res++;
// mark[i][j] = true;
// continue;
// }
// if (isPali(s.substring(i, j+1))) {
// mark[i][j] = true;
// res++;
// int tmpi = i, tmpj = j;
// while (tmpi - 1 >= 0 && tmpj + 1 < len) {
// if (s.substring(tmpi) == s.substring(tmpj)) {
// mark[tmpi][tmpj] = true;
// }
// tmpi--;
// tmpj++;
// }
// }
// }
// }
for (int l = len; l >= 1; l--) {
for (int i = 0; i <= len - l; i++) {
int j = i + l - 1;
if (mark[i][j]) {
res++;
continue;
}
if (i == j) {
res++;
mark[i][j] = true;
continue;
}
if (isPali(s.substring(i, j+1))) {
mark[i][j] = true;
res++;
int left = i + 1, right = j - 1;
while (left <= right) {
mark[left][right] = true;
left++;
right--;
}
}
}
}
return res;
}
boolean isPali(String str) {
int len = str.length();
int left = 0, right = str.length() - 1;
while (left < right) {
if (str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
}
题解
题解方法关注的是回文串所有可能的回文串中心点,然后从中心点往两边扩散,比我这种要好很多。我这种其实是O(n3)。
然后还有就是一个对我来说的新算法Manacher 算法