LeetCode挑战:最小代价构造回文串与分割回文串的动态规划与状态压缩技巧

本文探讨了如何使用动态规划解决LeetCode中的两道回文串问题——最小代价构造回文串和分割回文串。通过思路分析和代码实现,详细解释了如何利用状态压缩技巧来优化算法,降低复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

LeetCode1312之最小代价构造回文串

思路分析

代码实现

LeetCode131. 分割回文串

思路分析

代码实现

相关拓展

参考文章


前言

动态规划的通用套路和状态压缩技巧具有很强的通用性

LeetCode1312之最小代价构造回文串

给你一个字符串 s ,每一次操作你都可以在字符串的任意位置插入任意字符。

请你返回让 s 成为回文串的 最少操作次数 。「回文串」是正读和反读都相同的字符串。

示例 1:

输入:s = "zzazz"
输出:0
解释:字符串 "zzazz" 已经是回文串了,所以不需要做任何插入操作。

示例 2:

输入:s = "mbadm"
输出:2
解释:字符串可变为 "mbdadbm" 或者 "mdbabdm" 。


示例 3:

输入:s = "leetcode"
输出:5
解释:插入 5 个字符后字符串变为 "leetcodocteel" 。


示例 4:

输入:s = "g"
输出:0


示例 5:

输入:s = "no"
输出:1

思路分析

我们定义一个二维的dp数组,dp[i][j]的定义如下:对字符串s[i..j],最少需要进行dp[i][j]次插入才能变成回文串

我们想求整个s的最少插入次数,根据这个定义,也就是想求dp[0][n-1]的大小(ns的长度)。

同时,base case 也很容易想到,当i == jdp[i][j] = 0,因为当i == js[i..j]就是一个字符,本身就是回文串,所以不需要进行任何插入操作。

假设为s[i+1..j-1]已经是一个回文串了,所以通过dp[i+1][j-1]推导dp[i][j]的关键就在于s[i]s[j]这两个字符

 这个得分情况讨论,如果s[i] == s[j]的话,我们不需要进行任何插入,只要知道如何把s[i+1..j-1]变成回文串即可:

 如果s[i] != s[j]的话,就比较麻烦了,比如下面这种情况

最简单的想法就是,先把s[j]插到s[i]右边,同时把s[i]插到s[j]右边,这样构造出来的字符串一定是回文串:

但是,这是不是就意味着代码可以直接这样写呢?

if (s[i] != s[j]) {
    // 把 s[j] 插到 s[i] 右边,把 s[i] 插到 s[j] 右边
    dp[i][j] = dp[i + 1][j - 1] + 2;
}

不对,比如说如下这两种情况,只需要插入一个字符即可使得s[i..

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据与算法架构提升之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值