当前位置: 首页 > news >正文

算法第四十六天:动态规划part13(第九章)

1.回文子串

📌 核心思路

  1. 定义 dp[i][j]:表示子串 s[i..j] 是否为回文。

  2. 状态转移:

    • 情况一:单个字符必然是回文 → j == i

    • 情况二:两个字符相等 → s[i] == s[j]j - i == 1

    • 情况三:长度大于 2 时 → s[i] == s[j] and dp[i+1][j-1] == True

  3. 遍历顺序:i 从右往左,j 从左往右,保证计算 dp[i+1][j-1] 时已经有结果。

class Solution:def countSubstrings(self, s: str) -> int:#dp[i][j]是表示s[i, j]是否是回文字串#初始化dp = [[False] * len(s) for _ in range(len(s))]count = 0#递归公式for i in range(len(s)-1, -1, -1):for j in range(i, len(s)):if s[i] == s[j]:if j-i <= 1: #情况1和2count += 1dp[i][j] = Trueelif dp[i+1][j-1]:#情况3:长度大于2count += 1dp[i][j] = Truereturn count

2.最长回文子序列

📝 最长回文子序列(LPS)思路总结

1. 问题定义

给定字符串 s,求其中的 最长回文子序列(subsequence)的长度。
⚠️ 注意:子序列可以不连续,但必须保持原有顺序;和 子串(substring) 不同。


2. 动态规划状态定义

设二维数组:

dp[i][j]=字符串 s[i..j] 的最长回文子序列长度dp[i][j] = \text{字符串 } s[i..j] \text{ 的最长回文子序列长度}dp[i][j]=字符串 s[i..j] 的最长回文子序列长度


3. 状态转移方程

  1. 如果 s[i] == s[j]

    • i == j:只有一个字符,dp[i][j] = 1

    • j == i+1:两个字符相等,dp[i][j] = 2

    • 一般情况:

      dp[i][j]=dp[i+1][j−1]+2dp[i][j] = dp[i+1][j-1] + 2dp[i][j]=dp[i+1][j−1]+2
  2. 如果 s[i] != s[j]

    dp[i][j]=max⁡(dp[i+1][j],dp[i][j−1])dp[i][j] = \max(dp[i+1][j], dp[i][j-1])dp[i][j]=max(dp[i+1][j],dp[i][j−1])

4. 边界条件

  • 单个字符:

    dp[i][i]=1dp[i][i] = 1dp[i][i]=1

5. 遍历顺序

  • 因为 dp[i][j] 依赖 dp[i+1][j-1]dp[i+1][j]dp[i][j-1],所以必须 从右往左枚举 i从左往右枚举 j


6. 答案

最终答案是:

dp[0][n−1]dp[0][n-1]dp[0][n−1]

即整个字符串的最长回文子序列长度。

class Solution:def longestPalindromeSubseq(self, s: str) -> int:#dp[i][j]表示s[i, j]之间的最长回文子序列的长度#初始化dp = [[0] * len(s) for _ in range(len(s))]#单个字符是回文for i in range(len(s)):dp[i][i] = 1#递归公式for i in range(len(s)-1, -1, -1):for j in range(i+1, len(s)):if s[i] == s[j]:if j == i+1:dp[i][j] = 2else: dp[i][j] = dp[i+1][j-1] + 2else:dp[i][j] = max(dp[i+1][j], dp[i][j-1])return dp[0][-1]

动态规划终于结束了!!!撒花儿~

总结如下:代码随想录

http://www.dtcms.com/a/335040.html

相关文章:

  • STM32 软件I2C读写MPU6050
  • Redis入门与背景详解:构建高并发、高可用系统的关键基石
  • Linux系统编程练习、作业
  • Flink Stream API 源码走读 - 总结
  • 差分约束.
  • 腾讯混元大模型:实现3D打印产品生成的自动化平台
  • [Python 基础课程]继承
  • [Linux] RAID存储技术
  • 【102页PPT】电子行业数字化解决方案(附下载方式)
  • 容器化部署:用Docker封装机器翻译模型与服务详解
  • 服务器可以ping通,但部署的网站打不开
  • MyBatis 的 SQL 拦截器:原理、实现与实践
  • 基于Spring Boot的快递物流仓库管理系统 商品库存管理系统
  • OpenStack Neutron中的L2 Agent与L3 Agent:新手友好指南
  • Nginx蜘蛛请求智能分流:精准识别爬虫并转发SEO渲染服务
  • RemoteCtrl-初步的网络编程框架搭建
  • Linux 多线程:线程回收策略 线程间通信(互斥锁详解)
  • Easytier异地组网与Nginx反向代理
  • 昇腾AI自学Day2-- 深度学习基础工具与数学
  • 楼宇自控系统赋能建筑全维度管理,实现环境、安全与能耗全面监管
  • 计算分组内时间列的最大差值
  • 【AI论文】NextStep-1:迈向大规模连续令牌自回归图像生成
  • Warning: Unable to create personal MATLAB work folder:E:\绯荤粺榛樿\鏂囨。\MATLAB
  • 1083. 数列极差问题
  • 【深度学习】基于ESRNet模型的图像超分辨率训练
  • pytest介绍(python测试框架)(@pytest.mark.parametrize、@pytest.fixtures)
  • ClaudeCode使用指南
  • 鲁老师深度学习笔记(1)—最大似然估计
  • Flutter Provider 模式实现:基于 InheritedWidget 的状态管理实现
  • 93、23种设计模式之抽象工厂模式