【算法】力扣【动态规划,LCS】1312. 让字符串成为回文串的最少插入次数

这篇具有很好参考价值的文章主要介绍了【算法】力扣【动态规划,LCS】1312. 让字符串成为回文串的最少插入次数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1312. 让字符串成为回文串的最少插入次数


【算法】力扣【动态规划,LCS】1312. 让字符串成为回文串的最少插入次数

题目描述

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

问题的核心是给定一个字符串s,你可以在任意位置插入任意字符,要求通过最小次数的操作将原字符串转变为回文串。回文串定义为正序与倒序读起来都相同的字符串。

例如:

  • 示例 1:
    输入:s = “zzazz”
    输出:0
    **解释:**字符串 “zzazz” 已经是回文串了,因此无需任何插入操作。

  • 示例 2:
    输入:s = “mbadm”
    输出:2
    **解释:**字符串可以通过插入字符变为 “mbdadbm” 或 “mdbabdm”,使其成为回文串。

  • 示例 3:
    输入:s = “leetcode”
    输出:5
    **解释:**经过插入5个字符后,字符串可以变为 “leetcodocteel”,成为回文串。

提示:

  • 1 <= s.length <= 500
  • s中所有字符都是小写字母。

解题思路

解决这一问题的关键在于理解回文串的结构特性与最长公共子序列(LCS)之间的联系。对于任意一个字符串,其变换成为回文串所需的最少插入次数可以表示为:

最少插入次数 = len ( s ) − LPS ( s ) \text{最少插入次数} = \text{len}(s) - \text{LPS}(s) 最少插入次数=len(s)LPS(s)

其中 len ( s ) \text{len}(s) len(s)是字符串 s s s的长度, LPS ( s ) \text{LPS}(s) LPS(s) s s s的最长回文子序列的长度。

因此,我们的目标转化为寻找给定字符串的最长回文子序列。这可以通过对字符串进行逆序,然后寻找原字符串与逆序字符串的最长公共子序列来实现。如果我们记逆序字符串为 s ′ s^\prime s,则最长公共子序列可表示为:

LCS ( s , s ′ ) \text{LCS}(s, s^\prime) LCS(s,s)

对于字符串 s s s的每个可能的子问题,我们定义状态 d p [ i ] [ j ] dp[i][j] dp[i][j]表示字符串 s s s的前 i i i个字符与其逆序字符串的前 j j j个字符的最长公共子序列的长度。我们通过动态规划的方法,自底向上地计算这些状态值,状态转移方程为:

d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] + 1 if  s [ i ] = s ′ [ j ] max ⁡ ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) else dp[i][j] = \begin{cases} dp[i-1][j-1] + 1 & \text{if } s[i] = s^\prime[j] \\ \max(dp[i-1][j], dp[i][j-1]) & \text{else} \end{cases} dp[i][j]={dp[i1][j1]+1max(dp[i1][j],dp[i][j1])if s[i]=s[j]else

具体地,我们初始化一个二维数组 d p dp dp,其中 d p [ i ] [ j ] dp[i][j] dp[i][j]代表 s s s的前 i i i个字符与 s ′ s^\prime s的前 j j j个字符的最长公共子序列的长度。我们将此数组全部初始化为0,然后迭代填表,最终 d p [ len ] [ len ] dp[\text{len}][\text{len}] dp[len][len] len \text{len} len s s s的长度)将给出我们所需的最长回文子序列的长度。最后,字符串 s s s的长度减去这一值即为答案:

最少插入次数 = len ( s ) − d p [ len ] [ len ] \text{最少插入次数} = \text{len}(s) - dp[\text{len}][\text{len}] 最少插入次数=len(s)dp[len][len]

解题代码

class Solution {
public:
    int minInsertions(string s) {
        size_t len = s.size();
        int dp[len + 1][len + 1];

        // 初始化dp数组
        for (int i = 0; i <= len; ++i) {
            for (int j = 0; j <= len; ++j) {
                dp[i][j] = 0;
            }
        }

        // 动态规划填表
        for (int i = 1; i <= len; ++i) {
            for (int j = 1; j <= len; ++j) {
                // 逆序字符串与原字符串比较
                if (s[i - 1] == s[len - j]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        // 最终结果为原字符串长度减去最长回文子序列的长度
        return len - dp[len][len];
    }
};

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n是字符串s的长度。我们需要填充一个 n × n n \times n n×n的二维数组。
  • 空间复杂度: O ( n 2 ) O(n^2) O(n2),用于存储动态规划表的空间。

总结

本文介绍了如何通过动态规划的方式来解决将字符串转变为回文串的最少插入次数问题。关键在于理解并找出最长回文子序列,其长度与原字符串长度之差即为所求。这种算法不仅展示了动态规划解决问题的强大之处,同时也提供了对回文串性质的深入理解。在实际应用中,这类算法也常用于文本处理和生物信息学等领域。文章来源地址https://www.toymoban.com/news/detail-819392.html

到了这里,关于【算法】力扣【动态规划,LCS】1312. 让字符串成为回文串的最少插入次数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【算法】力扣【动态规划,LCS】1143. 最长公共子序列

    1143. 最长公共子序列 本文是对 LCS 这一 动态规划 模型的整理,以力扣平台上的算法题1143:最长公共子序列为模板题进行解析。 该题目要求计算两个字符串的最长公共子序列(Longest Common Subsequence,简称LCS)的长度。字符串的子序列是指在不改变字符顺序的情况下,通过删去

    2024年01月17日
    浏览(61)
  • 【力扣·每日一题】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)

    题目链接 给你一个字符串 word ,你可以向其中任何位置插入 “a”、“b” 或 “c” 任意次,返回使 word 有效 需要插入的最少字母数。 如果字符串可以由 “abc” 串联多次得到,则认为该字符串 有效 。 提示: 1 = w o r d . l e n g t h = 50 1 = word.length = 50 1 = w or d . l e n g t h = 50 w

    2024年01月16日
    浏览(51)
  • 【动态规划】【字符串】C++算法:正则表达式匹配

    视频算法专题 动态规划汇总 字符串 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘ ’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 \\\' ’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 示例 1: 输入:

    2024年02月03日
    浏览(57)
  • 【面试算法——动态规划 21】正则表达式匹配(hard)&& 交错字符串

    链接: 10. 正则表达式匹配 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ‘*’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 示例 1: 输入:s = “aa”

    2024年02月08日
    浏览(52)
  • 剑指offer(C++)-JZ46:把数字翻译成字符串(算法-动态规划)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 有一种将字母编码成数字的方式:\\\'a\\\'-1, \\\'b-2\\\', ... , \\\'z-26\\\'。 现在给一串数字,返回有多少种可能的译码结果 数据范围:字符串长度满足 0n≤90 进阶:空间复杂度

    2024年02月07日
    浏览(47)
  • 剑指offer(C++)-JZ48:最长不含重复字符的子字符串(算法-动态规划)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 数据范围:  s.length≤40000 s.length≤40000 示例: 输入: 返回值: 说明

    2024年02月06日
    浏览(58)
  • 【动态规划】【字符串】扰乱字符串

    视频算法专题 动态规划汇总 字符串 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 1 ,执行下述步骤: 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符

    2024年02月03日
    浏览(60)
  • 【算法详解】力扣415.字符串相加

    力扣链接:力扣415.字符串相加 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。 示例 1: 输入:num1 = “11”, num2 = “123” 输出:

    2024年01月22日
    浏览(44)
  • 【学会动态规划】环绕字符串中唯一的子字符串(25)

    目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 学习一个算法没有捷径,更何况是学习动态规划, 跟我一起刷动态规划算法题,一起学会动态规划! 题目链接:467. 环绕字符串中唯一的子字

    2024年02月10日
    浏览(38)
  • 动态规划--通配字符串匹配

    1. 题目来源 链接:通配符匹配 来源:LeetCode 2. 题目说明 给定一个字符串 (s) 和一个字符模式 § ,实现一个支持 ‘?’ 和 ‘*’ 的通配符匹配。 ‘?’ 可以匹配任何单个字符。 ‘*’ 可以匹配任意字符串(包括空字符串)。 两个字符串完全匹配才算匹配成功。 说明: s 可能为

    2024年02月14日
    浏览(52)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包