647. 回文子串

题目描述

给你一个字符串 sss ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

示例 1 :

输入 :s = "abc"

输出 :3

解释:三个回文子串: "a", "b", "c"

示例 2 :

输入 :s = "aaa"

输出 :6

解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

算法思想

状态表示 :对于 sss,用 dpijdpijdpij 表示 i,ji, ji,j 这段子串是否为回文串,其中 (i<=j)(i <= j)(i<=j)。比如 0,20, 20,2 这段子串如果是回文串,dp02dp02dp02 就是 truetruetrue,否则就是 falsefalsefalse

状态转移方程 :填表时要固定 iii,让 jjj 从 iii 位置开始一直向后移动来枚举以 iii 位置开始的所有子串,如下图所示

对 sisisi 和 sjsjsj 进行分析,得出状态转移方程

  1. si==sjsi == sjsi==sj 时,如果 i==ji == ji==j,说明子串只有一个字符,肯定是回文,dpij=truedpij = truedpij=true。如果 i+1==ji + 1 == ji+1==j,说明子串只有两个字符,这两个字符还一样,肯定是回文,dpij=truedpij = truedpij=true。如果 i+1<ji + 1 < ji+1<j,说明子串不只两个字符,中间还有一段 i+1,j−1i +1, j - 1i+1,j−1 的子串,如果这段子串是回文,那 i,ji, ji,j 这段子串肯定是回文了,所以 dpij=dpi+1j−1dpij = dpi+1j-1dpij=dpi+1j−1
  2. si!=sjsi != sjsi!=sj 时,肯定不是回文,dpij=falsedpij = falsedpij=false

初始化 :初始化是为了填表不越界,如果以 dpi+1j−1dpi+1j-1dpi+1j−1 的值填 dpijdpijdpij,当 j==0j == 0j==0 和 i==n−1i == n - 1i==n−1 时会越界,但是 i<=ji <= ji<=j,所以此时 iii 肯定等于 jjj,就直接填 truetruetrue 了,不会越界,不需要初始化

填表顺序 :由于 dpijdpijdpij 依赖于 dpi+1j−1dpi+1j-1dpi+1j−1 的值,所以要从下往上填

返回值 :dpdpdp 表中 truetruetrue 的个数

代码

cpp 复制代码
class Solution {
public:
    int countSubstrings(string s) 
    {
        int n = s.size();
        vector<vector<int>> dp(n, vector<int>(n, false));

        int ret = 0;
        for (int i = n - 1;i >= 0;--i)
        {
            for (int j = n - 1;j >= i;--j)
            {
                if (s[i] == s[j])
                {
                    dp[i][j] = j <= i + 1 ? true : dp[i + 1][j - 1];
                    // if (i == j) dp[i][j] = true;
                    // else if (i == j - 1) dp[i][j] = true;
                    // else dp[i][j] = dp[i + 1][j - 1];
                }
                
                if (dp[i][j])
                {
                    ret++;
                }
            }
        }
        return ret;
    }
};
相关推荐
怕浪猫3 小时前
GEO 优化到底是什么?AI时代内容创作者必须懂的新技能
算法·面试·github
朝朝辞暮i4 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
Evand J5 小时前
【MATLAB例程】三维RRT+APF避障路径规划与到达角(AOA)定位算法|三维路径优化与定位仿真例程
算法·matlab·路径规划·代码·定位·rrt·aoa
郑同学的笔记5 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
随意起个昵称6 小时前
【背包dp】输出方案路径
c++·动态规划
weixin_307779136 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
朝朝辞暮i6 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
by209997 小时前
学会使用std::string类,并理解其内部是如何管理字符串的详细阐述(上)
c++·笔记·字符串·类和对象·string
沙漠之主7 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
朝朝辞暮i7 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法