一、题目
二、代码
1.0:
class Solution {
public:
/**
* @param s: the string
* @return: the number of substring
*/
//判断是否是回文串
bool isHui(string s,int i,int j)
{
int len=j-i+1;
//子串结束坐标
int en=j+1;
//子串开始坐标
for(int st=i;st<len/2+st;st++)
{
en--;
if(s[st]==s[en]) continue;
else return false;
}
return true;
}
int countSubstrings(string &s) {
// Write your code here.
int res=0;
//子串起始坐标
for(int i=0;i<s.size();i++)
{
//子串终止坐标
for(int j=i;j<s.size();j++)
{
if(isHui(s,i,j)) res++;
}
}
return res;
}
};
此思路采用完全枚举的方法,即将所有子串都列举出来,并自定义一个判断回文的函数,让其判断这些子串是否是回文串。很显然,这种方法到最后超时了,因为随着字符串的长度增加,子串的个数呈很大的增长速度。
上述的方法很显然是存在冗余的,比如s="abba",其中"bb"和“abba”的回文判断是独立的,实际上在确定"bb"为回文后,左右两边均为'a',则可以得出“abba”也是回文。
于是,我们考虑优化。我们通过找“中心点”的方式来判断回文串。中心点又分为2种情况:①选取1个字母为中心点,②选取2个字母的中间为中心点
代码如下:
class Solution {
public:
/**
* @param s: the string
* @return: the number of substring
*/
int n;
//注意:由样例知回文子串的个数是不算重复的
//所以定义一个set来存储回文子串的个数
set<string> res;
int countSubstrings(string &s) {
// Write your code here.
n=s.size();
//中心点为字符
for(int i=0;i<n;i++) isHui(s,i,i);
//中心点为两字符中间
for(int i=0;i<n-1;i++) isHui(s,i,i+1);
return res.size();
}
//判断是否是回文串
void isHui(string &s,int l,int r)
{
//选定中心点,向两边扩展
//从中间向两边发散
//只要有一个地方不等了,那while就结束了
//因为后面就更不可能相等了
while (l>=0&&r<n&&s[l]==s[r])
{
//是回文子串就放入集合
res.insert(s.substr(l,r-l+1));
l--;
r++;
}
}
};