赞
踩
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
1 <= s.length <= 1000
s
由小写英文字母组成//定义判断回文字串函数 int countSubstrings(string s) { int length=s.size(); //建立动态规划数组 vector<vector<int>>dp(length,vector<int>(length)); //统计状态转移方程中1的数目 int count=0; //由于对角线的元素一定是回文,初始化对角线元素 for(int i=0;i<length;i++) { dp[i][i]=1; count++; } //建立动态转移方程 //从字串的长度中,到字符串长度不断增加 for(int sublength=2;sublength<=length;sublength++) { //从字符串左边进行枚举 //i为字符字串的左端点 for(int i=0;i<length;i++) { //j为字符字串,作为字符串的右端点 int j=i+sublength-1; if(j>=length) { break; } //判断左端点和右端点是否相等 if(s[i]!=s[j]) { dp[i][j]=0; } else{ //当字符串的长度在1,2,3只要两个端点两边相等就一定是回文字串 if(j-i+1<4) { dp[i][j]=1; count++; } else{ //dp[i+1][j-1]是指靠近两个端点内部的字串是否为回文字串 dp[i][j]=dp[i+1][j-1]; if(dp[i][j]) { count++; } } } } } return count; }
//使用中心扩散法 int countSubstrings2(string s) { int ans=0; //中心点有2*len-1,分别为len个单字符和len-1个双字符 //中心点即left指针和right指针初始化指向的地方,可能是一个也可能是两个 for(int center=0;center<2*s.size()-1;center++) { int left=center/2; int right=left+center%2; while(left>=0&&right<s.size()&&s[left]==s[right]) { ans++; //向两边进行扩散 left--; right++; } } return ans; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。