【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

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

目录

动态规划

动态规划思维(基础)

状态表示(最重要)

状态转移方程(最难)

初始化(细节)

填表顺序(细节)

返回值(结果)

回文子串 ⭐⭐

【题目解析】 

【算法原理】

C++ 算法代码 

最长回文子串 ⭐⭐ 

【题目解析】 

【算法原理】

C++ 算法代码  

回文串分割Ⅳ⭐⭐⭐ 

【题目解析】 

【算法原理】

C++ 算法代码


动态规划

动态规划思维(基础)

        动态规划一般会先定义一个dp表,dp表一般为一维数组 / 二位数组。如:一维数组,会先创建一个一维数组(dp表),接下来就是想办法将这个dp填满,而填满之后里面的某一个值就是最终结果。

状态表示(最重要)

#问:是什么?

  • 就是dp[i]所代表的含义。

#问:怎么来?

  • 题目要求。
  • 经验 + 题目要求。
  • 分析问题的过程中,发现重复子问题。

状态转移方程(最难)

#问:是什么?

  • dp[i] = ?。

初始化(细节)

#问:有什么作用?

  • 保证填表的时候不越界。

        dp表是根据状态转移方程进行的,而状态转移方程是通过已有状态推出未知状态。

填表顺序(细节)

#问:有什么作用?

  • 为了填写当前状态的时候,所需要的状态已经计算过了。

返回值(结果)

        题目要求 + 状态表示。

⭐⭐⭐DP解回文串问题核心:能够将所有的字串是否是回文的信息,保存在dp表中。


回文子串 ⭐⭐

 647. 回文子串 - 力扣(LeetCode)


【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

【题目解析】 

        为了能表示出来所有的子串,我们可以创建⼀个 n * n 的⼆维 dp 表,只用到「上三角部分」即可。 其中, dp[i][j] 表示: s 字符串 [i, j] 的子串,是否是回文串

【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

        每层逻辑。

【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

【算法原理】

#:状态表示:

        为了能表示出来所有的子串,我们可以创建⼀个 n * n 的⼆维 dp 表,只用到「上三角部分」
即可。 其中, dp[i][j] 表示: s 字符串 [i, j] 的子串,是否是回文串。

#:状态转移方程:

对于回文串,我们⼀般分析⼀个「区间两头」的元素:
  • 当 s[ i ] != s[ j ] 的时候:不可能是回文串, dp[ i ][ j ] = false
  • 当 s[ i ] == s[ j ] 的时候:根据长度分三种情况讨论:
    • 长度为 1 ,也就是 i == j :此时一定是回文串, dp[ i ][ j ] = true
    • 长度为 2 ,也就是 i + 1 == j :此时也一定是回文串, dp[ i ][ j ] = true
    • 长度大于 2 ,此时要去看看 [ i + 1, j - 1 ] 区间的子串是否回文: dp[ i ][ j ] = dp[i + 1][j - 1] 

#:初始化:

         因为我们的状态转移方程分析的很细致,因此无需初始化。

#:填表顺序:

        根据「状态转移方程」,我们需要「从下往上」填写每⼀行,每⼀行的顺序无所谓。

#:返回值:

        根据「状态表示和题目要求」,我们需要返回 dp 表中 true 的个数。 


C++ 算法代码 

class Solution {
public:
    int countSubstrings(string s) {
        int ret = 0;
        // 1、创建dp表
        vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));

        // 2、初始化

        // 3、填表
        for(int i = s.size() - 1; i >= 0; i--)
        {
            for(int j = i; j < s.size(); j++)
            {
                if(s[i] == s[j])
                    dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;
                if(dp[i][j]) 
                    ret++; // 统计个数
            }
        }
        return ret;
    }
};

最长回文子串 ⭐⭐ 

5. 最长回文子串 - 力扣(LeetCode)


【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

【题目解析】 

        与上一题一样。

【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

【算法原理】

#:状态表示:

        为了能表示出来所有的子串,我们可以创建⼀个 n * n 的⼆维 dp 表,只用到「上三角部分」
即可。 其中, dp[i][j] 表示: s 字符串 [i, j] 的子串,是否是回文串。

#:状态转移方程:

对于回文串,我们⼀般分析⼀个「区间两头」的元素:
  • 当 s[ i ] != s[ j ] 的时候:不可能是回文串, dp[ i ][ j ] = false
  • 当 s[ i ] == s[ j ] 的时候:根据长度分三种情况讨论:
    • 长度为 1 ,也就是 i == j :此时一定是回文串, dp[ i ][ j ] = true
    • 长度为 2 ,也就是 i + 1 == j :此时也一定是回文串, dp[ i ][ j ] = true
    • 长度大于 2 ,此时要去看看 [ i + 1, j - 1 ] 区间的子串是否回文: dp[ i ][ j ] = dp[i + 1][j - 1] 

#:初始化:

        因为我们的状态转移方程分析的很细致,因此无需初始化。

#:填表顺序:

        根据「状态转移方程」,我们需要「从下往上」填写每⼀行,每⼀行的顺序无所谓。

#:返回值:

        根据「状态表示和题目要求」,我们需要返回 dp 表中 true 的个数。 


C++ 算法代码  

class Solution {
public:
    string longestPalindrome(string s) {
        int ret_max = 0;
        int begin_index = 0;
        // 1、创建dp表
        vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));

        // 2、初始化

        // 3、填表
        for(int i = s.size() - 1; i >= 0; i--)
        {
            for(int j = i; j < s.size(); j++)
            {
                if(s[i] == s[j])
                    dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;

                if(dp[i][j] && j - i + 1 > ret_max) 
                {
                    ret_max = j - i + 1 ;
                    begin_index = i;     
                }
            }
        }

        // 4、返回值
        return s.substr(begin_index, ret_max);
    }
};

回文串分割Ⅳ⭐⭐⭐ 

1745. 回文串分割 IV - 力扣(LeetCode)


【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

【题目解析】 

        与上题和上上题一样。

【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

        因为其能够将所有的字串是否是回文的信息,保存在dp表中。所以我们只需要在前述中,最后加入一个判断。

【动态规划专栏】-- 回文串问题 -- 动态规划经典题型

【算法原理】

#:状态表示:

        为了能表示出来所有的子串,我们可以创建⼀个 n * n 的⼆维 dp 表,只用到「上三角部分」
即可。 其中, dp[i][j] 表示: s 字符串 [i, j] 的子串,是否是回文串。

#:状态转移方程:

对于回文串,我们⼀般分析⼀个「区间两头」的元素:
  • 当 s[ i ] != s[ j ] 的时候:不可能是回文串, dp[ i ][ j ] = false
  • 当 s[ i ] == s[ j ] 的时候:根据长度分三种情况讨论:
    • 长度为 1 ,也就是 i == j :此时一定是回文串, dp[ i ][ j ] = true
    • 长度为 2 ,也就是 i + 1 == j :此时也一定是回文串, dp[ i ][ j ] = true
    • 长度大于 2 ,此时要去看看 [ i + 1, j - 1 ] 区间的子串是否回文: dp[ i ][ j ] = dp[i + 1][j - 1] 

#:初始化:

        因为我们的状态转移方程分析的很细致,因此无需初始化。

#:填表顺序:

        根据「状态转移方程」,我们需要「从下往上」填写每⼀行,每⼀行的顺序无所谓。

#:返回值:

        根据「状态表示和题目要求」,我们需要返回 dp[0][i - 1] && dp[i][j] && dp[j + 1][s.size() - 1] 循环判断。 文章来源地址https://www.toymoban.com/news/detail-479508.html


C++ 算法代码

class Solution {
public:
    bool checkPartitioning(string s) {
        
        // 1、创建dp表
        vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));

        // 2、初始化

        // 3、填表
        for(int i = s.size() - 1; i >= 0; i--)
        {
            for(int j = i; j < s.size(); j++)
            {
                if(s[i] == s[j])
                    dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;
            }
        }

        // 4、返回值
        for(int i = 1; i < s.size() - 1; i++)
        {
            for(int j = i; j < s.size() - 1; j++)
            {
                if(dp[0][i - 1] && dp[i][j] && dp[j + 1][s.size() - 1])
                    return true;
            }
        }
        return false;
    }
};

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

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

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

相关文章

  • 【动态规划】背包问题题型及方法归纳

    【动态规划】背包问题题型及方法归纳

    背包问题是在规定背包容量为j的前提下,每个物品对应的体积为v[i],价值为w[i],从物品0到物品i中选择物品放入背包中, 找出符合某种要求的价值 。 (1)背包问题种类 01背包:每种物品只能选择1个。 完全背包:每种物品可以选择无限个。 多重背包:每种物品最多可选

    2024年02月02日
    浏览(6)
  • 动态规划——回文串问题

    动态规划——回文串问题

    目录 练习1:回文子串 练习2:最长回文子串 练习3:回文串分割IV 练习4:分割回文串 练习5:最长回文子序列 练习6:让字符串成为回文串的最小插入次数 本篇文章主要学习使用动态规划来解决回文串相关问题,我们通过相关练习来学习 题目链接: 647. 回文子串 - 力扣(Le

    2024年04月09日
    浏览(8)
  • 【动态规划】回文串问题

    【动态规划】回文串问题

    题目链接 状态表示 f[i][j]表示 i 到 j 的子串当中是否是回文 状态转移方程 初始化 最初所有的内容都是0即可 填表 因为 i j 需要用 i + 1 来初始化,所以这个时候需要从下往上填表 返回值 返回整个dp 表里true 的数目就可以 AC代码: 题目链接 如果需要求一个字符串当中的最长的回

    2024年02月09日
    浏览(11)
  • 动态规划--回文串问题

    动态规划--回文串问题

    一)回文子串: 647. 回文子串 - 力扣(LeetCode) 思路1:暴力枚举: for(int i=0;iarray.length;i++) for(int j=i;jarray.length;j++) 我们的中心思路就是枚举出所有的子字符串,然后进行判断所有的子串是否是回文串 每一次我们固定i位置,j向后走, 就成功枚举出了以i位置为起点的所有回文字串的

    2024年04月22日
    浏览(5)
  • 动态规划之回文串问题

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

    2024年02月07日
    浏览(8)
  • c++--动态规划回文串问题

    c++--动态规划回文串问题

    1.回文子串   力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给定一个字符串 s ,请计算这个字符串中有多少个回文子字符串。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。 示例 1: 示例 2: 分析:   2.最长回文串  力扣(

    2024年02月11日
    浏览(6)
  • 动态规划课堂6-----回文串问题

    动态规划课堂6-----回文串问题

    目录 引言: 例题1:回文子串 例题2:回文串分割IV 例题3:分割回文串II 例题4:最长回文子序列 例题5:让字符串成为回文串的最小插入次数 回文字符串  是正着读和倒过来读一样的字符串。 动态规划的回文串问题一般是把 子串 是否是回文串的信息保持在dp表里面,所以更

    2024年03月18日
    浏览(9)
  • 【动态规划专栏】专题二:路径问题--------1.不同路径

    【动态规划专栏】专题二:路径问题--------1.不同路径

    本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:动态规划专栏 🚚代码仓库:小小unicorn的代码仓库🚚

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

    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日
    浏览(8)
  • 【动态规划专栏】专题二:路径问题--------6.地下城游戏

    【动态规划专栏】专题二:路径问题--------6.地下城游戏

    本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:动态规划专栏 🚚代码仓库:小小unicorn的代码仓库🚚

    2024年02月22日
    浏览(17)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包