• 代码随想录训练营第五十七天|647. 回文子串、516.最长回文子序列


     647. 回文子串

    题目链接/文章讲解/视频讲解:代码随想录

    1.代码展示

    1. //647.回文子串
    2. int countSubstrings(string s) {
    3. //step1 构建dp数组,明确dp数组的含义,dp[i][j]的含义是在下标为i和j区间内的字串是否为回文串
    4. vectorbool>> dp(s.size(), vector<bool>(s.size(), false));
    5. //step2 构建状态转移方程
    6. //当s[i] != s[j]时,此时必定不为回文子串
    7. //当s[i] == s[j]时,有三种情况
    8. //情况一:i = j,此时就是本身,因此必定为回文子串
    9. //情况二:i + 1 = j,此时就如aa的形式,因此也是回文子串
    10. //情况三:j > i + 1,此时当dp[i + 1][j - 1]为回文字串时,dp[i][j]才是回文子串
    11. //step3 初始化dp数组,都为false
    12. //step4 开始遍历
    13. int nResult = 0;
    14. for (int i = s.size() - 1; i >= 0; i++) {
    15. for (int j = i; j < s.size(); j++) {
    16. if (s[i] == s[j]) {
    17. if (j - i <= 1) {
    18. nResult++;
    19. dp[i][j] = true;
    20. }
    21. else if (dp[i + 1][j - 1]){
    22. nResult++;
    23. dp[i][j] = true;
    24. }
    25. }
    26. }
    27. }
    28. return nResult;
    29. }

     2.本题小节

            思考:本题的重点在于对于dp[i][j]的理解,dp[i][j]的含义是在下标为i和j区间内的字串是否为回文串。构建状态转移方程,当s[i] != s[j]时,此时必定不为回文子串;当s[i] == s[j]时,有三种情况
     ,情况一,i = j,此时就是本身,因此必定为回文子串, 情况二,i + 1 = j,此时就如aa的形式,因此也是回文子串,情况三:j > i + 1,此时当dp[i + 1][j - 1]为回文字串时,dp[i][j]才是回文子串;初始化都为false,最后注意遍历顺序,先下后上,先左后右。

            基本思路:注意理解dp[i][j]的含义,按照代码的思路来即可。

    516.最长回文子序列

    题目链接/文章讲解/视频讲解:代码随想录

    1.代码展示

    1. //516.最长回文子序列
    2. int longestPalindromeSubseq(string s) {
    3. //step1 构建dp数组,dp[i][j]的含义是在[i,j]下标的范围内s的最长回文子序列
    4. vectorint>> dp(s.size(), vector<int>(s.size(), 0));
    5. //step2 状态转移方程
    6. //当s[i] == s[j],dp[i][j] = dp[i + 1][j - 1] + 2,
    7. //不等时,有两种情况,说明同时加入s[i],s[j]不能满足情况,分别加入s[i]和s[j]试试
    8. //则dp[i][j] = max(dp[i][j - 1], dp[i + 1][j])
    9. //step3 初始化
    10. for (int i = 0; i < s.size(); i++) {
    11. dp[i][i] = 1;
    12. }
    13. //step4 开始遍历
    14. for (int i = s.size() - 1; i >= 0; i++) {
    15. for (int j = i + 1; j < s.size(); j++) {
    16. if (s[i] == s[j]) {
    17. dp[i][j] = dp[i + 1][j - 1] + 2;
    18. }
    19. else {
    20. dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
    21. }
    22. }
    23. }
    24. return dp[0][s.size() - 1];
    25. }

     2.本题小节

            思考:明确dp数组的含义。dp[i][j]的含义是在[i,j]下标的范围内s的最长回文子序列。状态转移方程,当s[i] == s[j],dp[i][j] = dp[i + 1][j - 1] + 2,不等时,有两种情况,说明同时加入s[i],s[j]不能满足情况,分别加入s[i]和s[j]试试,则dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]),初始化时对角线都为1,根据dp数组可以得。遍历时先下后上,先左后右。

            基本思路:注意dp数组的含义,按照动态规划步骤来。

    动态规划总结:代码随想录

  • 相关阅读:
    node-sass为什么一直安装不上、安装失败?
    Win11如何给系统盘瘦身?Win11系统盘瘦身方法
    【GDB】 .gdbinit 文件
    Polygon L2扩容方案揭秘
    使用VsCode调试UE5的PuerTs
    SpringSecurity详解,实现自定义登录接口
    manjaro gnome 记录 3 配置国内镜像源
    开源共建 | TIS整合数据同步工具ChunJun,携手完善开源生态
    ConcurrentHashMap
    猿创征文|Hadoop大数据技术
  • 原文地址:https://blog.csdn.net/weixin_62453859/article/details/132742566