題目地址:
https://leetcode-cn.com/probl...
題目描述:
給定一個字符串,你的任務是計算這個字符串中有多少個迴文子串。
具有不同開始位置或結束位置的子串,即使是由相同的字符組成,也會被計爲是不同的子串。
示例 1:
輸入: "abc"
輸出: 3
解釋: 三個迴文子串: "a", "b", "c".
示例 2:
輸入: "aaa"
輸出: 6
說明: 6個迴文子串: "a", "a", "a", "aa", "aa", "aaa".
注意:
輸入的字符串長度不會超過1000。
解答:
這一題可以用窮舉法,檢查s[i...j]是否爲迴文字串但是應該會超時。
不過我們可以這麼想,如果現在知道了s[i...j]是迴文字串,那麼如果
s[i-1] == s[j+1],那麼s[i-1...j+1]也一定是迴文字串。這樣就聯想到了
動態規劃。
設置dp[i] [j]表示s[i...j]是否是迴文字串,若是爲true,否則爲false。
那麼對任意的dp[i] [j] = dp[i+1] [j-1]&&s[i]==s[j]。一旦爲true就把
結果+1。
不過需要注意的是要使用上述的遞推公式,需要先求出所有長度爲1和爲2的迴文字串,這個比較
簡單,就不贅述了。
java ac代碼:
class Solution {
public int countSubstrings(String s) {
//dp[i][j]表示s[i...j]是否爲迴文字串。
boolean[][] dp = new boolean[s.length()][s.length()];
int ans = 0;
for(int i = 0;i < dp.length;i++)
{
dp[i][i] = true;
ans++;
}
for(int i = 1;i < dp.length;i++)
if(s.charAt(i-1) == s.charAt(i))
{
dp[i-1][i] = true;
ans++;
}
for(int k = 2;k < s.length();k++)
for(int i = k;i < s.length();i++)
if(s.charAt(i-k) == s.charAt(i)&&dp[i-k+1][i-1])
{
dp[i-k][i] = true;
ans++;
}
return ans;
}
}