(力扣—动态规划)回文子串
描述
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。
示例 1:
输入: “abc”
输出: 3
解释: 三个回文子串: “a”, “b”, “c”.
示例 2:
输入: “aaa”
输出: 6
说明: 6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”.
注意:
输入的字符串长度不会超过1000。
思想
这道题其实和之前的一道最长回文子串很类似,所以dp思想很简单,这里就不多说了。
另外忍不住吐槽一下c++,一定要注意在用c++有关长度的内置函数的时候,最好不要直接用,而是重新int一个变量存储
因为大部分有关长度的内置函数类型是unsigned,如果直接用有关长度的内置函数直接进行运算 有时候会出现一些意想不到的错误
python code
class Solution:
def countSubstrings(self, s: str) -> int:
dp = [[0 for i in range(len(s))] for i in range(len(s))] # 初始化dp数组
for i in range(len(s)): dp[i][i] = 1 # 初始化字符串长度为1的
for i in range(len(s) - 1): # 初始化长度为2的
if s[i] == s[i + 1]:
dp[i][i + 1] = 1
k = 2
for i in range(len(s) - 2):
for j in range(len(s) - k):
if s[j] == s[j + k] and dp[j + 1][j + k - 1]:
dp[j][j + k] = 1
k += 1
Sum = 0
for temp in dp:
Sum += sum(temp)
return Sum
c++ code
class Solution {
public:
int countSubstrings(string s) {
int s_length = s.length(); //长度一定要单独获取 因为s.length()是unsigned类型
vector<vector<int>> dp(s_length, vector<int>(s_length)); //初始化dp数组
for(int i = 0; i < s_length; i++)
dp[i][i] = 1; //字符本身必回文
for(int i = 0; i < s_length - 1; i++)
if(s[i] == s[i + 1])
dp[i][i + 1] = 1; //初始化长度为2的字符串回文情况
int k = 2; //初试相隔数
for(int i = 0; i < s_length; i++){ //还剩下s.length() - 2种长度的子串
for(int j = 0; j < s_length - k; j++)
if(s[j] == s[j + k] && dp[j + 1][j + k - 1])
dp[j][j + k] = 1;
k++;
}
int sum = 0;
for(vector<int> temp: dp)
for(int figure: temp)
sum += figure;
return sum;
}
};