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

news2024/11/29 8:43:27

给你一个字符串 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]; // 返回整个字符串的最长回文子序列长度
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TrinityCore安装记录

TrinityCore模拟魔兽世界&#xff08;World of Warcraft&#xff09;的开源项目&#xff0c;并且该项目代码广泛的优化、改善和清理代码。 前期按照官方手册按部就班的安装即可。 注意几点&#xff1a; 1 需要配置Ubuntu22.04版本的服务器或者Debian11 服务器。2 需要使用gi…

python_ACM模式《剑指offer刷题》链表4

题目&#xff1a; 面试tips&#xff1a; 询问是否需要判断环&#xff0c;可微调下方代码。 思路&#xff1a; 思路一&#xff1a; 判断环是否存在&#xff1a;设定一快一慢指针&#xff0c;均从头节点出发&#xff0c;快指针一次走两步&#xff0c;慢指针一次走一步。若无环…

docker安装-centos

Docker CE 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10 卸载旧版本Docker sudo yum remove docker \ docker-common \ docker-selinux \ docker-engine使用yum安装 yum 更新到最新版本: sudo yum update执行以下命令安装依赖包&#xff1a; sudo yum…

[设计模式Java实现附plantuml源码~结构型]处理多维度变化——桥接模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

SpringBoot第二天

Bean管理 Bean扫描 在Spring中&#xff0c;Bean的扫描有两种写法 第一种是在xml配置文件中用标签扫描 <context:component-scan basepackage"com.cacb"/> 第二种是是注解扫描 ComponentScan(basePackages"com.cacb") 而在SpringBoot中&#xf…

张维迎《博弈与社会》威胁与承诺(4)宪政与民主

有限政府 动态博弈理论对我们理解民主与法治具有重要的意义。 自人类进入文明时代以来&#xff0c;政府就是社会博弈重要的参与人。任何社会要有效运行&#xff0c;都需要赋予政府一些自由裁量权。但如果政府的自由裁量权太大&#xff0c;政府官员为所欲为&#xff0c;不仅老百…

Jetson AGX Orin安装Anaconda,Cuda,Cudnn,pytorch,Tensorrt,ROS

Anaconda&#xff1a;https://repo.anaconda.com/archive/ Cuda&#xff1a;https://forums.developer.nvidia.com/t/pytorch-for-jetson/72048 1&#xff1a;安装Anaconda3 下载&#xff1a;Anaconda3-2021.11-Linux-aarch64.sh chmod x Anaconda3-2021.11-Linux-aarch64.s…

瑞_23种设计模式_工厂模式

文章目录 1 什么是工厂模式案例案例代码 2 简单工厂模式&#xff08;Simple Factory&#xff09;2.1 简单工厂模式的结构2.2 案例改进——简单工厂模式2.3 案例改进代码实现2.4 简单工厂模式优缺点2.5 拓展——静态工厂 3 工厂方法模式&#xff08;Factory Method&#xff09;★…

OJ_整数奇偶排序

题干 c实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<algorithm> using namespace std;//compare函数不交换返回true bool compare(int a, int b) {//1.a奇数&#xff0c;b偶数&#xff0c;不交换//2.a奇数&#xff0c;b奇数&#xff0c;a比b…

openGauss学习笔记-213 openGauss 性能调优-总体调优思路

文章目录 openGauss学习笔记-213 openGauss 性能调优-总体调优思路213.1 调优思路概述213.2 调优流程 openGauss学习笔记-213 openGauss 性能调优-总体调优思路 213.1 调优思路概述 openGauss的总体性能调优思路为性能瓶颈点分析、关键参数调整以及SQL调优。在调优过程中&…

【Redis】整理

对于现代大型系统而言&#xff0c;缓存是一个绕不开的技术话题&#xff0c;一提到缓存我们很容易想到Redis。 Redis整理&#xff0c;供回顾参考

TiDB架构设计和实践:高性能分布式数据库解决方案

摘要&#xff1a;TiDB是一个开源的分布式NewSQL数据库&#xff0c;具备强大的水平扩展能力和高性能查询能力。本文将介绍TiDB的架构设计和实践经验&#xff0c;帮助读者了解如何利用TiDB构建可靠、高性能的分布式数据库系统。 正文&#xff1a; ### 1. 引言 随着互联网规模的…

Struts2远程代码执行漏洞复现

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、漏洞介绍 Struts2漏洞是一个经典的漏洞系列&#xf…

探索智能巡检机器人深度学习的奥秘

机器人深度学习&#xff08;Robot Deep Learning&#xff09;是指利用深度学习技术&#xff0c;使机器人能够从大量数据中学习和提取特征&#xff0c;进而实现自主感知、决策和行动的能力。通过深度学习算法&#xff0c;机器人可以从传感器获取的数据中自动学习模式和规律&…

【SpringBoot】ApplicationContextAware 与 @Autowired 注解效果是一样,但是时机不一样

一、区别 ApplicationContextAware 是一个接口&#xff0c;它提供一个方法 setApplicationContext &#xff0c;当 spring 注册完成之后&#xff0c;会把 ApplicationContext 对象以参数的方式传递到方法里&#xff0c;在方法里我们可以实现自己的逻辑&#xff0c;去获取自己的…

深入了解关联查询和子查询

推荐阅读 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;一&#xff09; 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;二&#xff09; 文章目录 推荐阅读关联查询子查询 关联查询 关联查询 从多张表中查询对应记录的信息&#xff0c;关联查…

C++参悟:扩展资源

有用的资源 一、概述二、模式、手法、提示和技巧1. cpppatterns2. C Core Guidelines3. MSDN 三、第三方库 一、概述 在 cppreference 中我发现了很多比较有趣的扩展资源。我是从其官网下载的离线 chm 版本以便查看 https://zh.cppreference.com/w/%E9%A6%96%E9%A1%B5 在我下…

一款轻量级、高性能、功能强大的内网穿透代理服务器

简介 nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发&#xff0c;可支持任何tcp、udp上层协议&#xff08;访问内网网站、本地支付接口调试、ssh访问、远程桌面&#xff0c;内网dns解析等等……&#xff09;&#xff0c;此外还支持内网htt…

Python学习(15)|切片slice操作

38-切片 slice 操作类似字符串的切片操作&#xff0c;对于列表的切片操作和字符串类似。 切片操作&#xff1a; 切片是Python序列及其重要的操作&#xff0c;适用于列表、元组、字符串等。 切片slice操作可以让我们快速提取子列表或者修改。标准格式为&#xff1a; [起始偏移…

QT6调用音频输入输出(超详细)

目录 一、QT6音频调用与QT5的区别 1.QAudioSource代替QAudioInput类 2.QAudioSink代替QAudioOutput类 二、音频操作中Push和Pull的区别 三、依托于Websocket实现实时对讲机 1.AudioIputDevices类 2.AudioOutputDevices类 3.实现的AudioHandler类完整内容 本人实际是要完…