class Solution {
public:
    bool ifHuiWen(bool DP[1000][1000],int i,int j){
        if(i>=j){
            return true;
        }
        else{
            return DP[i][j];
        }
    }
    
    int countSubstrings(string s) {
        int n=s.length();
        if(n==0){
            return 0;
        }
        int count=0;
        bool DP[1000][1000];
        for(int i=0;i<n;i++){
            DP[i][i]=true;
        }
        count+=n;
        for(int len=1;len<n;len++){
            for(int i=0;i<n-len;i++){
                int j=i+len;
                if(s[i]!=s[j]){
                    DP[i][j]=false;
                }
                else{
                    DP[i][j]=ifHuiWen(DP,i+1,j-1);
                    if(DP[i][j]){
                        count++;
                    }
                }
            }
        }
        
        return count;
    }
};

 

参考另外一个python的实现,解释的比较容易懂,代码思路和上面的是一样的。

 1 def countSubstrings(self, s):
 2     if not s:
 3         return 0
 4 
 5     n = len(s)
 6     table = [[False for x in range(n)] for y in range(n)]
 7     count = 0
 8 
 9     # Every isolated char is a palindrome
10     for i in range(n):
11         table[i][i] = True
12         count += 1
13 
14     # Check for a window of size 2
15     for i in range(n-1):
16         if s[i] == s[i+1]:
17             table[i][i+1] = True
18             count += 1
19 
20     # Check windows of size 3 and more
21     for k in range(3, n+1):
22         for i in range(n-k+1):
23             j = i+k-1
24             if table[i+1][j-1] and s[i] == s[j]:
25                 table[i][j] = True
26                 count += 1
27 
28     return count

定义二维数组,table进行动态规划的记录。table[i][j]表示字符串s中,下标i到下标j之间的字符是否是回文字符,true表示:是回文;false表示:不是回文。

10~12行,第一次循环,将对角线上元素进行标记,全部标记为True,因为每一个单独字符都可以当作一个回文字符。

15~18行,第二次循环,将蓝色斜线进行标记,判断连续的两个字符是否相同,如果相同标记为True,否则标记为Flase。

12~26行,第三次循环,将剩下的橘色,品红和红色等进行标记,k的取值范围是从3到n,本例中n等于5。

k==3时,标记橘色,当其左下角位置为True,并且i元素和j元素字符相同(i与j相差2个位置,即i为0时j为2,i为1时j为3...以此类推)

k==4时,标记品红,当其左下角位置为True,并且i元素和j元素字符相同(i与j相差3个位置,即i为0时j为3,i为1时j为4...以此类推)

k==5时,标记红色,当期左下角位置为Ture,并且i元素和j元素字符相同(i与j相差4个位置,即i为0时j为4,以此类推)

这里的"左下角"表示:当前长度为k的子字符串,除去第0位和第k-1位后,"内部"的字符串是否是回文。

例如:s='abcbca',假设此时k=3,则会分别依次判断:

abcbca —> abc,此时"左下角"表示的就是内部的字符b,而两头的ac不相同,因此标记为False。

abcbca —> bcb,此时"左下角"表示的就是内部的字符c,而两头的bb相同,因此标记为True。

abcbca —> cbc,此时"左下角"表示的就是内部的字符b,而两头的cc相同,因此标记为True。

abcbca —> bca,此时"左下角"表示的就是内部的字符c,而两头的ba不相同,因此标记为False。

在此上三角矩阵中(含对角线),所有标记为True的就是一个回文字符,True的个数就是所求。

参考:https://leetcode.com/problems/palindromic-substrings/discuss/128581/Easy-to-understand-Python-DP-solution

posted on 2018-10-12 14:03  Sempron2800+  阅读(190)  评论(0编辑  收藏  举报