【刷题题解】最长回文子序列

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列

这道题,一眼动态规划,但是即使动起来也规划不了一点😅

好,这道题,我们可以这样子思考,先把视线聚焦在单个字符上,单个字符是s【i】就是一个回文字符串,所以,在此基础上,我们去扩展他的左右两边,如果s【i-1】==s【i+1】,那么回文字符串的长度加上这两个元素的长度2(即加2),否则,当前字符串的最长回文子字符串长度为max(包含左边界的最长字串长度,包含右边界的最长字符串)

大致思路就是这样子,我们用程序来拆分。

对于字符串 s,设 dp[i][j] 表示子串 s[i...j] 中最长回文子序列的长度。我们想要计算的最终结果是 dp[0][n-1],其中 n 是字符串 s 的长度。

  • 初始化:对于任何字符串,如果取长度为 1,即 i == j,那么最长回文子序列的长度就是 1,因为每个单独的字符都是一个回文序列。所以,dp[i][i] = 1 对所有 0 <= i < n

  • 状态转移方程

    • 如果 s[i] == s[j],那么我们找到了一对匹配的字符,可以在 s[i+1...j-1] 的基础上增加 2,即 dp[i][j] = dp[i+1][j-1] + 2
    • 如果 s[i] != s[j],那么最长回文子序列要么在 s[i+1...j] 中,要么在 s[i...j-1] 中,所以 dp[i][j] = max(dp[i+1][j], dp[i][j-1])
  • 填表顺序:由于计算 dp[i][j] 需要知道 dp[i+1][j-1]dp[i+1][j]dp[i][j-1] 的值,因此我们需要从底部开始填表,即从 i = n-1 开始向 i = 0 遍历,同时 ji 开始向 n-1 遍历。

首先,通过Array.from和箭头函数初始化一个二维数组dp,然后按照状态转移方程填充这个数组。最后,返回dp[0][n - 1]的值作为整个字符串s的最长回文子序列长度。

function longestPalindromeSubseq(s) {
    const n = s.length;
    const dp = new Array(n).fill(0).map(() => new Array(n).fill(0));

    // 初始化,单个字符的情况
    for (let i = 0; i < n; i++) {
        dp[i][i] = 1;
    }

    // 填表
    for (let i = n - 2; i >= 0; i--) { // 从倒数第二行开始向上
        for (let j = i + 1; j < n; j++) { // 从左到右
            if (s[i] === s[j]) {
                dp[i][j] = dp[i + 1][j - 1] + 2;
            } else {
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[0][n - 1]; // 返回整个字符串的最长回文子序列长度
}

我看有人提出将字符串翻转,然后求两个字符串的最长公共子序列就可以了。

这个思路是基于:字符串的最长回文子序列与其翻转后字符串的最长公共子序列(Longest Common Subsequence, LCS)长度相同。这是因为回文子序列在原字符串中的顺序和在翻转字符串中的顺序是相反的,而LCS正是寻找这样的序列。

思路分析

  1. 翻转字符串:首先,得到原字符串s的翻转字符串reverseS
  2. 求最长公共子序列(LCS):然后,求原字符串s和翻转字符串reverseS的最长公共子序列的长度。这个长度即为原字符串的最长回文子序列的长度。

动态规划求LCS

对于字符串s和它的翻转字符串reverseS,设dp[i][j]表示s[0...i-1]reverseS[0...j-1]的最长公共子序列的长度。状态转移方程如下:

  • 如果s[i-1] == reverseS[j-1],那么dp[i][j] = dp[i-1][j-1] + 1
  • 否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])
function longestPalindromeSubseq(s) {
    const n = s.length;
    const reverseS = s.split('').reverse().join('');
    const dp = new Array(n).fill(0).map(() => new Array(n).fill(0));

    for (let i = 1; i <= n; i++) {
        for (let j = 1; j <= n; j++) {
            if (s[i - 1] === reverseS[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[n][n]; // 返回整个字符串的最长回文子序列长度
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/370872.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

总结了一下中继引擎(can中继器,TCP总机器)开发实际经验

多路数据进行中继的研究 1.数据中继的概念 数据中继是一种数据传输技术&#xff0c;用于在两个通信设备之间提供数字信号的传输。它利用数字信道传输数据信号&#xff0c;可以提供永久性和半永久性连接的数字数据传输信道。 数据中继的主要作用是提高通信质量和可靠性&#xf…

问题:金属电化学反应的实质是氧化还原反应,被腐蚀金属发生还原反应( ) #知识分享#知识分享#媒体

问题&#xff1a;金属电化学反应的实质是氧化还原反应&#xff0c;被腐蚀金属发生还原反应(  ) A、正确 B、错误 参考答案如图所示

解析Python中HTTP代理的常见问题

在Python编程中&#xff0c;HTTP代理是一个经常被提及的概念&#xff0c;尤其在处理网络请求和爬虫时。但与此同时&#xff0c;使用HTTP代理也经常会遇到一些令人头疼的问题。接下来&#xff0c;就让我们一起解析一下Python中使用HTTP代理时常见的那些问题。 1. 代理服务器无响…

如何在本地部署chatGLM3

文章目录 1. 参考2. ChatGLM3 介绍3. 本地运行3.1 硬件配置3.2 下载ChatGLM3代码3.3 下载需要加载的模型3.4 运行大模型3.4.1 ChatGLM3目录介绍3.4.2 安装依赖3.4.2 综合demo演示3.4.3 启动对话模式工具模式代码解释器 4. 总结 前面一章节有讲到 基于MacBook Pro M1芯片运行ch…

Debian系统显示中文

开发板上的debian默认不显示中文。 安装字体 sudo apt install fonts-wqy-zenhei 安装locals sudo apt install locales &#xff08;无必要&#xff09;设置/etc/locale.gen、设置/etc/locale.conf 运行dpkg-reconfigure locales dpkg-reconfigure locales 可以选择UT…

基于动作合成视频、线免费使用不需要注册,支持多种视频任务:图像生成视频、文本生成视频、视频修改、视频风格化、用Transformer构建世界模型

基于动作合成视频、线免费使用不需要注册&#xff0c;支持多种视频任务&#xff1a;图像生成视频、文本生成视频、视频修改、视频风格化、用Transformer构建世界模型。 WorldDreamer无缝逐帧AI模型: 基于Transformer生成高质量电影级别视频的通用世界模型"。从20亿数据中…

【linux】git和gdb调试工具

在linux下提交代码同步到gitee 1.创建一个新的仓库&#xff08;演示步骤&#xff09; 2.init 这两个步骤用于识别提交代码的身份&#xff0c;一个你的名字&#xff0c;一个你的邮箱 开启本地仓库 克隆本地仓库成功 我们将这个仓库拷到了111目录底下. 我们发现少了一个.gitig…

Fink CDC数据同步(五)Kafka数据同步Hive

6、Kafka同步到Hive 6.1 建映射表 通过flink sql client 建Kafka topic的映射表 CREATE TABLE kafka_user_topic(id int,name string,birth string,gender string ) WITH (connector kafka,topic flink-cdc-user,properties.bootstrap.servers 192.168.0.4:6668…

微信小程序使用ucharts折线图,有负数显示0刻度线

当数据有负数和正数的时候默认不会显示0刻度线&#xff0c;不方便看出正负对比 实现思路&#xff1a;显示的刻度线是根据数据的最大值和最小值自动分配到刻度线上面&#xff0c;把最大值和最小值设置为一样&#xff0c;然后平均分配给五个刻度线中间的刻度线就会为0就实现了显…

uniapp /微信小程序 使用map组件实现手绘地图方案

获取地图范围 点图拾取坐标-地图开放平台|腾讯位置服务 获取需要手绘地图左下角和右上角GPS坐标 以北京故宫为例&#xff1a; 截取需要手绘地图进行手绘地图制作 ​​​​​​​​​​​​​​ 素材处理 由于地图素材文件比较大&#xff0c;小程序又限制包大小<2M,无…

13.从桥接模式细品人生的几座桥

“物理学不存在了&#xff0c;今后也不会存在。”——《三体》 在《三体》中&#xff0c;有这样一个桥段&#xff0c;顶级的物理学家杨冬在三体文明超级计算机“智子”的干扰和误导下&#xff0c;得出了物理实验的结果在实验之前就会被某种力量确定的结论&#xff0c;导致自己…

PyTorch 2.2 中文官方教程(九)

在生产环境中部署 PyTorch 模型 通过 Flask 在 Python 中部署 PyTorch 的 REST API 原文&#xff1a;pytorch.org/tutorials/intermediate/flask_rest_api_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 注意 点击这里下载完整的示例代码 作者&#…

Windows鼠标右键菜单闪一下就没了?说不定是这个搞的鬼!

前言 这几天接到有些小伙伴反馈&#xff1a;Windows的右键菜单闪一下就没了。 本来是要按鼠标右键进行界面刷新或者新建文件夹等操作的&#xff0c;结果闪一下就没有了&#xff0c;感觉这个系统就好像中了病毒了一样。 相信很多小伙伴应该也遇到过同样的情况&#xff0c;但具…

BUGKU-WEB Simple_SSTI_1

02 Simple_SSTI_1 题目描述 解题思路 进入场景后&#xff0c;显示&#xff1a; You need pass in a parameter named flag。ctrlu 查看源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Simpl…

ElementUI 组件Layout布局 el-row和el-col 简介

Layout布局 el-row属性简介 el-row 组件 提供 gutter 属性来指定每一栏之间的间隔&#xff0c;默认间隔为 0。 提醒&#xff1a; el-row :gutter需要与el-col :span 一起使用才能生效 el-col属性简介 el-col的span属性 默认值为24&#xff0c;表示每一行共24份&#xff0c;:s…

030 可变参数

可变参数定义 public static void main(String[] args) {// 多参数方式传递System.out.println(max(1,3,5,3,6,1,2));// 数组方式传递System.out.println(max(new int[]{1,3,5,3,6,1,2})); }static int max(int... nums){int max Integer.MIN_VALUE;for (int num : nums) {if(…

Mysql架构系列——生产常用的高可用部署模式介绍

模式 高可用模式 Galera Cluster是由Codership开发的MySQL多主集群&#xff0c;包含在MariaDB中&#xff0c;同时支持Percona xtradb、MySQL&#xff0c;是一个易于使用的高可用解决方案&#xff0c;在数据完整性、可扩展性及高性能方面都有可接受的表现。 将会基于Galera C…

三层交换组网实验(华为)

思科设备参考&#xff1a;三层交换组网实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 三层交换技术的出现&#xff0c;解决子网必须依赖路由器进行管理的问题&#xff0c;解决传统路由器低速、复杂所造成的网络瓶颈问题。一个具有三层交换功能的设备可简单理解为…

2.4日总结

第一题&#xff1a;选数 题解&#xff1a;思路还是很简单的&#xff0c;只需要想清楚dfs里的函数都是什么就可以了&#xff0c;还有一个简单的判断素数的函数&#xff0c;这题真没啥难度&#xff0c;就是属于基础题吧&#xff0c;请看AC代码 #include <stdio.h> #includ…

redis的缓存击穿和缓存雪崩和缓存穿透问题解决方法

Redis的缓存击穿&#xff1a; 热点的key&#xff0c;在不停的扛着大并发&#xff0c;当这个key失效时&#xff0c;一瞬间大量的请求冲到持久层的数据库中&#xff0c;就像在一堵墙上某个点凿开了一个洞&#xff01; 解决方法&#xff1a; 1.热点key永不过期&#xff1a; 统计访…