【算法分析与设计】【第十四周】647. Palindromic Substrings

题目来源: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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值