【算法】动态规划—最长回文子序列

news2024/11/15 1:50:45

思路分析

        关于”回文串“的问题,是面试中常见的,本文提升难度,讲一讲”最长回文子序列“问题,题目很好理解:

        输入一个字符串 s,请找出 s 中的最长回文子序列长度。

        比如输入 s="aecda",算法返回3,因为最长回文子序列是 "aca",长度是3。

        这个问题对 dp 数组的定义是:在子串 s[i...j] 中,最长回文子序列的长度为 dp[i][j]。一定要记住这个定义才能理解算法。

        为什么这个问题要这样定义二维的 dp 数组呢?找状态转移需要归纳思维,说白了就是如何从已知的结果推出未知的部分,这样定义容易归纳,容易发现状态转移关系。

        具体来说,如果想求 dp[i][j],假设知道了子问题 dp[i+1][j-1] 的结果( s[i+1...j-1] 中最长回文子序列的长度),是否能想办法算出 dp[i][j] 的值( s[i...j] 中最长回文子序列的长度)呢?

        可以!这取决于 s[i] 和 s[j] 的字符:

        如果它俩相等,那么它俩加上 s[i+1...j-1] 中的最长回文子序列就是 s[i...j] 的最长回文子序列:

        如果它俩不相等,说明它俩不可能同时出现在 s[i...j] 的最长回文子序列中,那么把它俩分别加入 s[i+1...j-1]中,看看哪个子串产生的回文子序列更长即可:

        以上情况写成代码就是这样:

        if (s[i] == s[j])

                //  它俩一定在最长回文子序列中

                dp[i][j] = dp[i+1][j-1] + 2

        else

                // s[i+1...j] 和 s[i...j-1] 谁的回文子序列更长?

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

        至此,状态转移方程就写出来了,根据 dp 数组的定义,我们要求的就是 dp[0][n-1],也就是整个 s 的最长回文子序列的长度。

代码实现

        首先明确基本情况,如果只有一个字符,显然最长回文子序列长度是1,也就是 dp[i][j] = 1 (i == j)。因为 i 肯定小于或等于 j,所以对于那些 i > j 的位置,根本不存在什么子序列,应该初始化为0。另外,看看刚才写的状态转移方程,想求 dp[i][j] 需要知道 dp[i+1][j-1]、dp[i+1][j] 和 dp[i][j-1]这三个位置;再看看我们确定的基本情况,填入 dp 数组之后是这样的:

        为了保证每次计算 dp[i][j],左下右方向的位置已经被计算出来,只能斜着遍历或者反着遍历。这里选择反着遍历,代码如下:

package DynamicProgramming;

// leetcode 516 最长回文子序列
public class LCSS {

    public int longestPalindromeSubseq(String s) {
        int n = s.length();
        // 创建 dp 数组
        int[][] dp = new int[n][n];
        // base case
        for (int i = 0; i < n; i++) {
            dp[i][i] = 1;
        }
        // 反向遍历保证正确的状态转移
        for (int i = n - 2; i >= 0; i--) {
            for (int j = i + 1; j < n; j++) {
                // 状态转移方程
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }
        // 整个 s 的最长回文子序列长度
        return dp[0][n - 1];
    }

    public static void main(String[] args) {
        LCSS lcss = new LCSS();
        int len = lcss.longestPalindromeSubseq("aecda");
        System.out.println(len);
    }

}

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

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

相关文章

vscode中如何配置c/c++环境

“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言文章有误敬请斧正 不胜感恩&#xff01;一、准备工作二、安装 VSCode 插件三、配置 VSCode1. 配置编译任务&#xff08;tasks.json&#xff09;2. 配置调试器&#xff08;launch.json&#xff09; 四、运行和调…

用EA和SysML一步步建模(07)蒸馏器系统上下文图01

用EA和SysML一步步建模的操作指南&#xff08;01&#xff09; 用EA和SysML一步步建模&#xff08;02&#xff09;导入ISO-80000 用EA和SysML一步步建模&#xff08;03&#xff09;创建包图和包的关系 用EA和SysML一步步建模&#xff08;04&#xff09;创建“需求组织”包图 …

jd 京东h5st 最新版 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我…

尚品汇-秒杀列表、详情、倒计时、获取下单码(五十二)

目录&#xff1a; &#xff08;1&#xff09;秒杀列表与详情 &#xff08;2&#xff09;在service-activity-client模块添加接口 &#xff08;3&#xff09;秒杀详情页面功能介绍 &#xff08;1&#xff09;秒杀列表与详情 封装秒杀列表与详情接口、 封装接口 package com…

Python 解析 Charles JSON Session File (.chlsj)

Charles 代理&#xff0c;是一款抓包软件&#xff0c;可以帮助我们抓取浏览器请求跟响应。 1、在 Filter 里面输入需要抓包的网址 2、右键 Export Session 3、文件类型选择 JSON Session File (.chlsj) 保存 4、解析响应的数据结构 response.body.text 是文本字符串。 # 导入…

SOMEIP_ETS_113: SD_Empty_Options_Array

测试目的&#xff1a; 验证DUT能够拒绝一个选项数组长度为0的SubscribeEventgroup消息&#xff0c;并以SubscribeEventgroupNAck作为响应。 描述 本测试用例旨在确保DUT遵循SOME/IP协议&#xff0c;当接收到一个选项数组长度为0的SubscribeEventgroup消息时&#xff0c;能够…

网络设备登录——《路由与交换技术》实验报告

目录 一、实验目的 二、实验设备和环境 三、实验记录 1.通过 Console 登录 步骤1:连接配置电缆。 步骤2:启动PC,运行超级终端。 步骤3:进入Console 配置界面 2.通过 Telnet 登录 步骤1:通过 Console 接口配置 Telnet 用户。 步骤2:配置 super 口令 步骤3:配置登录欢迎…

Kamailio-基于Homer与heplify的SIP信令监控-3

接上2篇文章&#xff0c;你已经顺利地安装并部署了Homer相关服务&#xff0c;配置好了服务并顺利启动了。这个时候你已经算是搭建完成了一个SIP监控、分析体系&#xff0c;那应该怎么去用呢&#xff1f; 跟着我&#xff0c;你将学会&#xff1a; 下载并安装 踩坑&#xff1a;…

PyQt5-折叠面板效果

效果预览 实际效果中带有白色面板,看如下代码 实现代码 import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFrame, QLabel, QSizePolicy from PyQt5.QtCore import QPropertyAnimation, QEasingCurve, Qtclass CollapsiblePanel(QW…

夕阳红老年大学视频教学网站管理系统设计与实现,按用户最近浏览分类字段推荐视频课程-留言和评论分词过滤

目录 1. 选题社会意义 2. 选题技术意义 3. 功能介绍 4. 技术实现 随着人口老龄化的加剧&#xff0c;老年人的精神文化生活需求日益增加。传统的老年大学由于场地有限、师资力量不足等原因&#xff0c;难以满足广大老年人的学习需求。因此&#xff0c;开发一个面向老年人的在…

【C++】STL数据结构最全函数详解2-向量vector

关于STL&#xff0c;我们之前浅浅提过&#xff1a;这里 另外对于栈&#xff0c;这里有更加详尽的介绍&#xff1a;CSTL常用数据结构1详解---栈&#xff08;stack&#xff09;-CSDN博客 这个系列将会更加深入地从函数原型开始用详细的例子解释用法 首先这一篇介绍的是一个非常…

二叉树OJ题——二叉树的最大深度

文章目录 一、题目链接二、解题思路三、解题代码 一、题目链接 二叉树的最大深度 二、解题思路 三、解题代码

51单片机应用开发---数码管的控制应用

实现目标 1、掌握数码管结构、驱动原理及应用&#xff1b; 2、掌握数码管段码表推导&#xff1b; 3、会编程让开发板8个数码管动态显示。 一、什么是数码管&#xff1f; 1.数码管定义 数码管&#xff0c;也称为LED数码管&#xff0c;基本单元是发光二极管(LED)。分为七段数…

Makefile 学习笔记(一)gcc编译过程

环境准备 .linux 系统(虚拟机) VS code linux 编译过程 预处理: 把.h .c 展开形成一个文件.宏定义直接替换 头文件 库文件 .i 汇编&#xff1a; .i 生成一个汇编代码文件 .S 编译&#xff1a; .S 生成一个 .o .obj 链接: .o 链接 .exe .elf gcc c语言 g c语言 gcc的使用 …

钥匙和房间的题解——使用dfs或bfs进行图遍历

841. 钥匙和房间 这 n 个房间看成有向图中的 n 个节点&#xff0c;在x号房拿到了打开y号房的钥匙&#xff0c;可以看作是图中的 x 号点到 y 号点的一条有向边。 这样一来&#xff0c;问题就变成了给定一张有向图&#xff0c;询问从 0 号节点出发是否能够到达所有的节点。 DFS深…

1.3 计算机网络的分类

欢迎大家订阅【计算机网络】学习专栏&#xff0c;开启你的计算机网络学习之旅&#xff01; 文章目录 前言一、按分布范围分类二、按传输技术分类三、按拓扑结构分类四、按使用者分类五、按传输介质分类 前言 计算机网络根据不同的标准可以被分为多种类型&#xff0c;本章从分布…

【STL】 set 与 multiset:基础、操作与应用

在 C 标准库中&#xff0c;set 和 multiset 是两个非常常见的关联容器&#xff0c;主要用于存储和管理具有一定规则的数据集合。本文将详细讲解如何使用这两个容器&#xff0c;并结合实例代码&#xff0c;分析其操作和特性。 0.基础操作概览 0.1.构造&#xff1a; set<T&…

CefSharp_Vue交互(Element UI)_WinFormWeb应用(3)---通过页面锁屏和关机(含示例代码)

一、预览 实现功能:通过vue标题栏按钮锁屏和关机 1.1 预览 1.2 代码 锁屏代码csharp LockWorkStation() 关机代码chsharp 注意vue代码参数和此参数一致(0/1/2) 方法ExitWindowsEx()

春秋云境靶场之CVE-2022-29464

一.靶场环境 1.下载靶场 根据题目提示&#xff0c;存在文件上传漏洞 2.启动靶场 打开之后&#xff0c;页面显示 然后就跳转到一个登录页面 二.登录页面 1.尝试登录 我们尝试弱口令登录admin,admin&#xff0c;跳转到连接超时页面 当我们再次点击这个链接后&#xff0c;就会…

Leetcode面试经典150题-20.有效的括号

给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括…