题目
Given a string, your task is to count how many palindromic substrings in this string.
The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.
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".
Note:
The input string length won't exceed 1000.
答案
一开始我的想法是这样
定义numpal[i][j] = number of palindromic substrings between index i and j, inclusive
根据题目,我们想要求numpal[0][n-1]
basecase有numpal[i][i] = 1, for all i
但是要这样定义的话,似乎没法为numpal[i][j]写出一条recursion公式
也许,这道题没办法直接使用dp求解。
有的题目是这样,你要先用dp求解一个问题A的答案,然后再从这个问题A的答案里计算,从而得出你想要的答案。
我们试试尝试这个思路
定义ispal[i][j] = is the substring between index i and j a palindromic string?
basecase有有numpal[i][i] = true, for all i
recursion formula:
when s[i] == [j]
ispal = ispal[i + 1][j - 1]
有了ispal之后,如何利用这个数组来计算number of palindromic substrings of some string s?
这就很简单了
count = 0
for i = 0 to n -1
for j = i to n -1
if(ispal[i][j]) count++
return count
Implementation
One thing to note when implementing dp is you need to make sure
is that you must have everything that ispal[i][j] needs before you calculate ispal[i][j]
That means ispal[x][y] must exist before ispal[i][j], where x>i, y < j
class Solution {
public int countSubstrings(String s) {
boolean [][] ispal = new boolean[s.length()][s.length()];
int count = 0;
for(int i = s.length() - 1; i >= 0; i--) {
for(int j = i; j < s.length(); j++) {
if(i == j)
ispal[i][j] = true;
else if(j == i + 1)
ispal[i][j] = (s.charAt(i) == s.charAt(j));
else
ispal[i][j] = (s.charAt(i) == s.charAt(j) && ispal[i + 1][j - 1]);
if(ispal[i][j])
count++;
}
}
return count;
}
}
这道题的另外一种解法其实和Longest Palindromic Substring差不多,即以s[i]为中心expand,看看能得到多少个palindromic substring, for all i.
以下是网上的答案:
int count =1;
public int countSubstrings(String s) {
if(s.length()==0)
return 0;
for(int i=0; i=0 && j