给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。
示例 1:
输入: "abc" 输出: 3 解释: 三个回文子串: "a", "b", "c".
示例 2:
输入: "aaa" 输出: 6 说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa".
注意:
第一种思路:
暴力解,把所有子串找出来,再逐一判断是不是回文串。
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
res = 0
for i in range(len(s)):
for j in range(1, len(s) + 1 - i):
tmp = s[i:i + j]
if tmp == tmp[::-1]:
res += 1
return res
class Solution {
public int countSubstrings(String s) {
int n = s.length(), cnt = 0;
for (int i = 0; i < n; i++)
for (int j = i; j < n; j++){
boolean equals = true;
int ni = i, nj = j;
while(ni <= nj){
if (s.charAt(ni++) != s.charAt(nj--)){
equals = false;
break;
}
}
if (equals)
cnt++;
}
return cnt;
}
}
第二种思路:
动态规划,用dp[i][j]记录下s[i : j+1]是否是回文子串,如果是则dp[i][j] = 1, 不是则dp[i][j] = 0。
注意,如果i - j <= 1,则说明子串长度为0或者1,所以无需考虑dp[i - 1][j +1]。
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
#dp[i][j] 表示s[i:j+1] 是否为回文串
dp = [[0 for i in range(len(s))] for j in range(len(s))]
res = 0
for i in range(len(s)):
for j in range(i, -1, -1):
if s[i] == s[j] and (i - j <= 1 or dp[i - 1][j + 1]): #当i - j<=1时 不需要考虑dp[i-1][j+1]
dp[i][j] = 1
res += 1
return res
class Solution {
public int countSubstrings(String s) {
int n = s.length(), cnt = 0;
boolean[][] dp = new boolean[n][n];
for (int i = 0; i < n; i++)
for (int j = i; j >= 0; j--){
if (s.charAt(i) == s.charAt(j) && (i - j <= 1 || dp[i - 1][j + 1])){
dp[i][j] = true;
cnt++;
}
}
return cnt;
}
}
第三种思路:
中心扩散法,从长度为1的子串为中心向两边扩散,
分别判断以 s[i]为中心的子串和以s[i], s[i+1]为中心的子串是不是回文子串。
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
self.res = 0
def extend(left, right):
for i in range(len(s)):
while(left >= 0 and right < len(s) and s[left] == s[right]):
self.res += 1
left -= 1
right += 1
for i in range(len(s)):
extend(i, i)
extend(i, i+1)
return self.res
class Solution {
private int cnt = 0;
public int countSubstrings(String s) {
for (int i = 0; i< s.length(); i ++){
check(s, i, i);
check(s, i, i + 1);
}
return cnt;
}
public void check(String s, int start, int end){
while(start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)){
cnt++;
start--;
end++;
}
}
}