力扣647 回文子串
统计一个字符串中有多少个回文子串
中心扩展法:
(1)什么是中心点?中心点即 left 指针和 right 指针初始化指向的地方,可能是一个也可能是两个
(2)中心点一共有多少个?并不是和字符串长度length相等,而是2*length-1个,length个单字符作为中心,len-1个双字符作为中心(比如baab,就可以以双字符aa作为中心)
aba 有5个中心点,分别是 a、b、a、ab、ba,三个单字符作为中心,两个双字符作为中心
abba 有7个中心点,分别是 a、b、b、a、ab、bb、ba,四个单字符作为中心,三个双字符作为中心
class Solution {
public int result;
public int countSubstrings(String s) {
for(int i=0;i<s.length();i++)
{
help(s,i,i);//只有一个中心的情况
if(i<s.length()-1)
{
help(s,i,i+1);//有两个中心点的情况
}
}
return result;
}
public void help(String s,int left,int right)
{
while(left>=0&&right<s.length()&&s.charAt(left)==s.charAt(right))
{
result++;
left--;
right++;
}
}
}
class Solution
{
public String longestPalindrome(String s)
{
//从中心向两端扩散的双指针技巧
//回文串的长度可能是奇数,也可能是偶数
//有几个中心字符?如果回文串的长度为奇数,则它有一个中心字符;如果回文串的长度为偶数,则可以认为它有两个中心字符
String result="";
for(int i=0;i<s.length();i++)
{
//以 s[i] 为中心的最长回文子串
String s1=dfs(s,i,i);
//以 s[i] 和 s[i+1] 为中心的最长回文子串
String s2 = dfs(s, i, i + 1);
if(result.length()<s1.length())
{
result=s1;
}
if(result.length()<s2.length())
{
result=s2;
}
}
return result;
}
// 在 s 中寻找以 s[l] 和 s[r] 为中心的最长回文串
// 如果回文串的长度是奇数,只有1个中心字符,输入相同的l和r即可
//如果回文串的的长度是偶数,有两个中心字符,输入相邻的l和r
public String dfs(String s, int l, int r)
{
// 防止越界
while (l >= 0 && r < s.length()&& s.charAt(l) == s.charAt(r))
{
// 双指针,向两边展开
l--;
r++;
}
//跳出循环的时候,s.charAt(l)!=s.charAt(r),由于substring方法是左闭右开,所以是返回s.substring(l + 1, r);
// 返回以 s[l] 和 s[r] 为中心的最长回文串
return s.substring(l + 1, r);
}
}