題目來源:674 https://leetcode.com/problems/palindromic-substrings/description/
動態規劃基礎訓練。
647. Palindromic Substrings
題目大意
給定一個字符串,求出該字符串包含的所有迴文子串的個數。
Example 1:
Input: “abc”
Output: 3
Explanation: Three palindromic strings: “a”, “b”, “c”.Example 2:
Input: “aaa”
Output: 6
Explanation: Six palindromic strings: “a”, “a”, “a”, “aa”, “aa”, “aaa”.
思路
解這題之前先來複習一下兩道相關的題:求最長迴文子串
和最長迴文子序列
。
先區別一下這兩個概念:子串和子序列。
子串:XiXi+1Xi+2…Xj-1Xj,爲原串的某一連續部分。
子序列:可以爲原串的某一不連續部分。
例:
原串:todayisasunnyday
子串:isasunn
子序列:odand
相關回顧:最長迴文子串
和最長公共子串
本質一致,只需將原串作爲X串,原串逆過來作爲Y串,進行比較就可以了。
狀態轉移式:
// x爲原字符串,y爲原字符串逆置得到的串,f[i][j]表示從x[i]到y[j]之間的最長迴文子序列的長度
init:f[i][i] = 1
f[i][j] = f[i-1][j-1] ,x[i]=y[j],i!=j
f[i][j] = 0 ,x[i]!=y[j],i!=j
result:max{f[i][j]}
相關回顧:最長迴文子序列
《算法概論》P179的習題Ex6.7
狀態轉移式:
// str爲原字符串,f[i][j]表示從str[i]到str[j]之間的最長迴文子序列的長度
init:f[i][i] = 1
f[i][j] = f[i+1][j-1] + 2 ,str[i]=str[j],i!=j
f[i][j] = max{f[i+1][j], f[i][j-1]} ,str[i]!=str[j],i!=j
result:max{f[i][j]}
本題
狀態轉移式:
// str爲原字符串,(bool)isPal[i][j]表示從str[i]到str[j]是否是迴文
init:isPal[i][i] = true
isPal[i][j] = f[i+1][j-1] ,str[i]=str[j],i!=j,i+1<j-1
isPal[i][j] = true ,str[i]=str[j],i!=j,i+1>j-1
解題代碼
class Solution {
public:
int countSubstrings(string s) {
int size = s.length();
if (size <= 1) return 1;
bool isPal[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
isPal[i][j] = false;
}
}
for (int i = 0; i < size; i++) isPal[i][i] = true;
int count = size;
for (int j = 0; j < size; j++) {
for (int i = 0; i < j; i++) {
if (s[i] == s[j] && (isPal[i+1][j-1] || i+1 >= j-1) ) {
isPal[i][j] = true;
count++;
}
}
}
return count;
}
};
複雜度
O(n^2)