动态规划Day34:回文

647. 回文子串

DP 数组定义dp[i][j] 表示字符串 s 中,下标从 ij 的子串 s[i...j] 是否为回文子串(true= 是,false= 否)。

状态转移

  • s[i] == s[j]

    • 若子串长度≤2(j-i≤1,如单个字符、两个相同字符),直接判定为回文(dp[i][j]=true);

    • 若子串长度 > 2,则依赖内层子串 s[i+1...j-1] 的结果(dp[i+1][j-1]==true 时,dp[i][j]=true)。

遍历顺序 :从后往前遍历 i(保证计算 dp[i][j] 时,dp[i+1][j-1] 已被计算),ji 往后遍历(只处理 i≤j 的有效子串),每判定一个回文子串就计数 + 1。

cpp 复制代码
    int countSubstrings(string s) {
        vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
        int res = 0;
        for(int i = s.size() - 1; i >= 0; i--){
            for(int j = i; j < s.size(); j++){
                if(s[i] == s[j]){
                    if(j - i <= 1){
                        dp[i][j] = true;
                        res++;
                    } else if(dp[i + 1][j - 1] == true){
                        dp[i][j] = true;
                        res++;
                    }
                }
            }
        }
        return res;
    }

516. 最长回文子序列

求子序列,非连续,所以对不相等的情况还需要处理

DP 数组定义dp[i][j] 表示字符串 s 中,下标 ij 区间内的最长回文子序列长度

状态转移

  • s[i] == s[j]

    • 子区间长度 = 1(j-i=0):只有 1 个字符,dp[i][j]=1

    • 子区间长度 = 2(j-i=1):两个相同字符,dp[i][j]=2

    • 子区间长度 > 2:当前两个字符可拼接在内部最长回文子序列两侧,dp[i][j] = dp[i+1][j-1] + 2

  • s[i] != s[j]:取「去掉 i 的子区间」或「去掉 j 的子区间」的最大值,dp[i][j] = max(dp[i+1][j], dp[i][j-1])

遍历与结果

  • 逆序遍历 i(保证计算 dp[i][j] 时,dp[i+1][j]/dp[i][j-1] 已计算),ji 往后遍历;

  • 每次更新 res 为当前最大的 dp[i][j],最终 res 即为整个字符串的最长回文子序列长度。

cpp 复制代码
int longestPalindromeSubseq(string s) {
        vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
        int res = 0;
        for(int i = s.size() - 1; i >= 0; i--){
            for(int j = i; j < s.size(); j++){
                if(s[i] == s[j]){
                    if(j - i == 0){
                        dp[i][j] = 1;
                    }
                    else if(j - i == 1){
                        dp[i][j] = 2;
                    }
                    else if(dp[i + 1][j - 1] > 0){
                        dp[i][j] = dp[i + 1][j - 1] + 2;
                    }
                } else {
                    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
                }
                res = max(res, dp[i][j]);
            }
        }
        return res;
    }
相关推荐
t1987512812 分钟前
TOA定位算法MATLAB实现(二维三维场景)
开发语言·算法·matlab
jllllyuz13 分钟前
粒子群算法解决资源分配问题的MATLAB实现
开发语言·算法·matlab
renhongxia122 分钟前
从模仿到创造:具身智能的技能演化路径
人工智能·深度学习·神经网络·算法·机器学习·知识图谱
Sarvartha43 分钟前
递归、回溯与动态规划学习笔记
笔记·学习·动态规划
qq_401700411 小时前
顺序、二分、插值、斐波那契查找算法
数据结构·算法·排序算法
x_xbx1 小时前
LeetCode:26. 删除有序数组中的重复项
数据结构·算法·leetcode
WitsMakeMen1 小时前
RoPE 算法原理?算法为什么只和相对位置有关
人工智能·算法·llm
0 0 01 小时前
CCF-CSP 38-4 月票发行【C++】考点:动态规划DP+矩阵快速幂
c++·算法·动态规划·矩阵快速幂
北漂Zachary1 小时前
Mysql中使用sql语句生成雪花算法Id
sql·mysql·算法
aini_lovee2 小时前
MATLAB圆锥滚子轴承滚子参数分析程序
人工智能·算法·matlab