动态规划 回文子串

这篇具有很好参考价值的文章主要介绍了动态规划 回文子串。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

647. 回文子串
双指针法:

  1. 遍历回文中心---->一个回文中心---->两个回文中心
class Solution {
public:
    int countSubstrings(string s) {
        int result=0;
        for(int i=0; i<s.size(); i++){
            result += count(s, i, i);
            result += count(s, i, i+1);
        }
        return result;
    }
    int count(string s, int i, int j){
        int cnt=0;
        while(i>=0 && j<s.size() && s[i]==s[j]){
            cnt++;
            i--;
            j++;
        }
        return cnt;
    }
};
  1. 遍历边界,找出回文中心, 其实还是变相的找回文中心
class Solution {
public:
    int countSubstrings(string s) {
        int result = 0;
        int n = s.size();
        for(int i=0; i<n*2+1; i++){
            int left = i/2;
            int right = i/2 + (i+1)%2;
            while(left>=0 && right<n && s[left]==s[right]){
                result++;
                left--;
                right++;
            }
        }
    return result;
    }
};

动态规划:
4. dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false
5. 当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。
当s[i]与s[j]相等时

情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
情况二:下标i 与 j相差为1,例如aa,也是回文子串
情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。
  1. 遍历顺序—>dp[i + 1][j - 1] 从下向上从左到右
class Solution {
public:
    int countSubstrings(string s) {
        int n = s.size();
        vector<vector<int>>dp(n, vector<int>(n, 0));
        int cnt=0;
        for(int i=s.size()-1; i>=0; i--){
            for(int j=i; j<n; j++){
                if(s[i]==s[j]){
                    if(j-i<=1){
                         dp[i][j] = 1;
                         cnt++;
                    }else{
                        if(dp[i+1][j-1]==1){
                                dp[i][j] = 1;
                                cnt++;
                        }
                    }
                }
              
            }
        }
    return cnt;
    }
};

5. 最长回文子串

  1. 在判断回文子串的基础上,记录起始位置以及长度。
class Solution {
public:
    string longestPalindrome(string s) {
        int result = 1;
        int new_i =0;
        int n = s.size();
        vector<vector<int>>dp(n, vector<int>(n, 0));
        for(int i=n-1; i>=0; i--){
            for(int j=i; j<n; j++){
                if(s[i] == s[j] && (j-i<=1 || dp[i+1][j-1]==1)){
                    dp[i][j] = 1;
                    if(result <j-i+1){
                        result = j-i+1;
                        new_i =i;
                    }
                  
                }
            }
        }
        return s.substr(new_i, result);
    
    }
};

516. 最长回文子序列
相比于最长回文子串,回文子序列不考虑连续,可以进行删减。

  1. dp[i][j]:字符串s在[i, j]范围内最长的回文子序列的长度为dp[i][j]。
  2. 递推公式
    当s[i]与s[j]相等时 dp[i][j] = dp[i+1][j-1] + 2;
    当s[i]与s[j]不相等时删去最前面或者删去最后取最大 dp[i][j] = max(dp[i+1][j], dp[i][j-1]);
  3. 递推顺序: 从下到上 从左到右
  4. 初始化:递推公式是计算不到 i 和j相同时候的情况。所以需要手动初始化一下,当i与j相同,那么dp[i][j]一定是等于1的,
class Solution {
public:
    int longestPalindromeSubseq(string s) {
        int n = s.size();
        vector<vector<int>>dp(n, vector<int>(n, 0));
        for(int i=0; i<n; i++) dp[i][i] = 1;
        for(int i=n-1; i>=0; i--){
            for(int j=i+1; j<n; j++){
                if(s[i] == s[j]){
                    dp[i][j] = dp[i+1][j-1] + 2;
                }else{
                    dp[i][j] = max(dp[i+1][j], dp[i][j-1]);
                }
            }
        }
        return dp[0][n-1];
    }
};

思路2 1.s与s.reverse()的最长公共子序列即为其最长回文子序列文章来源地址https://www.toymoban.com/news/detail-614856.html

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        string text_1 = s;
        reverse(s.begin(), s.end());
        string text_2 = s;
        int n = s.size();
        vector<vector<int>>dp(n+1, vector<int>(n+1, 0));
     
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                if(text_1[i] == text_2[j]){
                    dp[i+1][j+1] = dp[i][j] + 1;
                }else{
                    dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]);
                }
            }
        }
        return dp[n][n];
    }
};

到了这里,关于动态规划 回文子串的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划——最长回文子串

    给你一个字符串 s ,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例 1: 示例 2: 1、动态规划算法 解题思路 (1)考虑 回文串的性质 :若一个子串是回文串并且 长度大于2 ,则将其 首尾两个字母去除 后,该子串仍然是一

    2024年04月08日
    浏览(40)
  • day57|动态规划17-最长回文子串问题

    回文子串:强调连续 回文子序列:不强调连续 暴力思路:三层for循环 双指针思路: 动态规划 dp数组 dp[i][j]: 根据字符串的形式和所解决的问题确定dp数组的形式和含义。 递归公式 (分情况讨论) 2.1 如果 i j 2.2 如果 j-i 1 2.3 如果 j-i1: 此时依赖于dp[i+1][j-1]是不是一个回文子

    2024年02月09日
    浏览(31)
  • 力扣第131题 分割回文串 c++ 回溯+简单 动态规划(是否为回文子串)

    131. 分割回文串 中等 相关标签 字符串   动态规划   回溯 给你一个字符串  s ,请你将   s   分割成一些子串,使每个子串都是  回文串  。返回  s  所有可能的分割方案。 回文串  是正着读和反着读都一样的字符串。 示例 1: 示例 2: 提示: 1 = s.length = 16 s  仅由小写

    2024年02月07日
    浏览(34)
  • 【算法】算法学习七:动态规划 | 背包问题 | 最长公共子串(含源代码)

    背包问题是一种经典的组合优化问题,通常有两个版本:0-1背包问题和无限背包问题。 0-1背包问题是指给定一个背包容量和一组物品,每个物品有自己的重量和价值,要求在不超过背包容量的情况下,选择一些物品放入背包,使得物品的总价值最大化。每个物品只能选择放入

    2024年02月09日
    浏览(34)
  • leetCode 131.分割回文串 + 动态规划 + 回溯算法 + 优化 + 图解 + 笔记

    我的往期文章: leetCode 647.回文子串 动态规划 + 优化空间 / 中心扩展法 + 双指针-CSDN博客 https://blog.csdn.net/weixin_41987016/article/details/133883091?spm=1001.2014.3001.5501 leetCode 131.分割回文串 + 回溯算法 + 图解 + 笔记-CSDN博客 https://blog.csdn.net/weixin_41987016/article/details/134700907?spm=1001.2014.3001

    2024年02月05日
    浏览(41)
  • 【动态规划】【二分查找】【C++算法】730. 统计不同回文子序列

    视频算法专题 动态规划汇总 二分查找算法合集 给你一个字符串 s ,返回 s 中不同的非空回文子序列个数 。由于答案可能很大,请返回对 109 + 7 取余 的结果。 字符串的子序列可以经由字符串删除 0 个或多个字符获得。 如果一个序列与它反转后的序列一致,那么它是回文序列

    2024年01月19日
    浏览(40)
  • 【算法沉淀】最长回文子串

     🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏 《数据结构与算法:初学者入门指南》📘📘 希望能和大家一起学习!共同进步! 这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://su

    2024年03月12日
    浏览(33)
  • 算法刷题|647.回文子串、516.最长回文子序列

    题目:给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。 d

    2024年02月17日
    浏览(37)
  • 最长子串和回文子串相关的算法题解

    中等 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s = “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: s = “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。 示

    2024年02月19日
    浏览(29)
  • 【算法】力扣【动态规划,LCS】1312. 让字符串成为回文串的最少插入次数

    1312. 让字符串成为回文串的最少插入次数 本文探讨的是力扣(LeetCode)上的第1312题:让字符串成为回文串的最少插入次数。这是一道属于动态规划类别下的困难题目,通常以回文串相关的操作来衡量算法的优化和执行效率。 问题的核心是给定一个字符串 s ,你可以在任意位

    2024年01月23日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包