想要精通算法和SQL的成长之路 - 最长回文子序列

2023-09-17 13:55:47

想要精通算法和SQL的成长之路 - 最长回文子序列

前言

想要精通算法和SQL的成长之路 - 系列导航

一. 最长回文子序列

原题链接

在这里插入图片描述
首先,我们看下动态规划方程的定义,我们用dp[i][j] 来代表:字符串s在下标区间为[i,j]之间的最长回文子序列。

那么请问,最终的返回结果,就是我们要求得字符串s的最长回文子序列,那也就是求得dp[0][len-1]的值。那么自然而然的,我们就需要自底向上的去递归。

  • 第一层循环:下标为left,范围:[0,len-1],我们从后往前遍历。
  • 第二层循环:下标为right,范围[left+1,len-1],从前往后遍历。

试想一下,第一层为啥要从后往前遍历?我们反过来想一下,如果从左往右遍历,那么第一层的第一次循环,left就是0,那么dp[0][len-1]是不是在第二层循环的末尾就直接算出来了?此时没有走完所有的场景。

那么写成代码就是:

for (int left = len - 1; left >= 0; left--) {
    for (int right = left + 1; right < len; right++) {
    }
}

紧接着,循环的时候,递归方程怎么写?根据题目意思,我们针对leftright对应的字符串分三种情况:

  • 如果s.charAt(left) == s.charAt(right)dp[left][right] = dp[left + 1][right - 1] + 2;
    在这里插入图片描述
  • 否则,左右两端不相等,那么此时左侧left的字符我们视为删除: dp[left][right] = dp[left + 1][right] ,要么右侧right的字符我们视为删除: dp[left][right] = dp[left][right - 1] ,两者取最大值。

因为我们的dp动态规划方程定义的是区间内的最大子序列长度,所以我们一定要做到区间的全覆盖性。我们必须选择左侧或者右侧的最近字符,并纳入计算。

最后还要注意一点的就是:回文子序列的最短长度是1,即单字符本身,我们要在每次外侧循环的时候,给个初始值。dp[left][left] = 1;

最后成代码就是:

public class Test516 {
    public int longestPalindromeSubseq(String s) {
        int len = s.length();
        int[][] dp = new int[len][len];
        for (int left = len - 1; left >= 0; left--) {
            dp[left][left] = 1;
            for (int right = left + 1; right < len; right++) {
                if (s.charAt(left) == s.charAt(right)) {
                    dp[left][right] = dp[left + 1][right - 1] + 2;
                } else {
                    dp[left][right] = Math.max(dp[left + 1][right], dp[left][right - 1]);
                }
            }
        }
        return dp[0][len - 1];
    }
}
更多推荐

客观题:Android基础【基础题】

一.单选题(共6题,60分)1.(单选题,10分)Android四层架构中,应用框架层使用的是什么语法?A.JavaB.AndroidC.CD.C++正确答案:AAndroid四层架构通常指的是Android应用的四个关键组件,包括:应用层(ApplicationLayer):这是最顶层的层次,包括用户界面(UI)和应

GaussDB技术解读系列:数据库迁移创新实践

近日,以“数智赋能共筑未来”为主题的第14届中国数据库技术大会(DTCC2023)在北京举行,在GaussDB“五高两易”核心技术,给世界一个更优选择的专场,华为云数据库生态工具研发总监窦德明分享了GaussDB数据库的迁移创新实践。本篇将分享GaussDB数据库迁移的创新实践。易迁移能力是企业数据库替换选型的关键考量

华硕电脑怎么录屏?分享实用录制经验!

“华硕电脑怎么录屏呀,刚买的笔记本电脑,是华硕的,自我感觉挺好用的,但是不知道怎么录屏,最近刚好要录一个教程,怎么都找不到在哪里录制,有人能教教我吗?”随着电脑技术的不断发展,人们越来越依赖电脑进行工作和娱乐。录屏功能作为电脑的一项重要功能,已经逐渐成为人们日常生活中的必备工具。华硕作为知名的电脑品牌,为用户提供了便捷

C语言——自定义类型结构体_学习笔记

结构体的基本概念结构体是一种用户自定义的数据类型,可以包含多个不同类型的变量。通过使用结构体,我们可以将相关联的数据组织在一起,便于管理和使用。结构体的声明正常的结构体声明在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型的一类。结构体可以包含多个不同类型的数据成员,例如:int、float、

linux的应用线程同步与驱动同步机制

同步机制在Linux应用程序和内核中的驱动程序中,有一些常见的同步机制用于实现线程或进程之间的同步和数据访问保护。下面是它们的一些主要机制:Linux应用程序中的同步机制:互斥锁(Mutex):用于保护共享资源,确保只有一个线程可以访问该资源。应用程序可以使用pthread_mutex_t类型的互斥锁,使用pthrea

爬虫入门基础:深入解析HTTP协议的工作过程

目录一、HTTP协议简介二、HTTP协议的工作过程三、请求方法与常见用途四、请求头与常见字段五、状态码与常见含义六、进阶话题和注意事项总结在如今这个数字化时代,互联网已经成为我们获取信息、交流和娱乐的主要渠道。而在互联网中,HTTP协议则扮演着至关重要的角色。HTTP,全称HypertextTransferProtoc

SpringMVC之JSR303和拦截器

目录一.JSR303二.JSR常用的注解三.JSR快速入门四.拦截器⭐⭐⭐拦截器和过滤器有什么不一样,或者它们的区别是什么??五.拦截器快速入门--登录的案例一.JSR303JSR303是Java规范的一部分,全称为BeanValidation框架。它定义了一组基于标注的验证注解,用于验证Java对象的属性值的合法性。

【Java 基础篇】ThreadPoolExecutor 详解

多线程编程是现代应用程序开发中的一个重要主题。为了更有效地管理和利用多线程资源,Java提供了丰富的线程池支持。ThreadPoolExecutor类是Java中用于创建和管理线程池的核心类之一,本文将详细介绍ThreadPoolExecutor的使用方法和原理。线程池的基本概念在深入探讨ThreadPoolExecu

leetcode 54. 螺旋矩阵

1.题解如果一条边从头遍历到底,则下一条边遍历的起点随之变化选择不遍历到底,可以减小横向、竖向遍历之间的影响一轮迭代结束时,4条边的两端同时收窄1一轮迭代所做的事情变得很清晰:遍历一个“圈”,遍历的范围收缩为内圈一层层向里处理,按顺时针依次遍历:上、右、下、左。不再形成“环”了,就会剩下:一行或一列,然后单独判断矩阵不

计算机竞赛 机器视觉opencv答题卡识别系统

0前言🔥优质竞赛项目系列,今天要分享的是🚩答题卡识别系统-opencvpython图像识别该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!🥇学长这里给一个题目综合评分(每项满分5分)难度系数:3分工作量:3分创新点:3分🧿更多资料,项目分享:https://gitee.com/dancheng-senior

Vue路由及Node.js环境搭建

目录一.Vue路由1.1定义1.2应用领域1.3代码展示二、Node.js2.1定义2.2特点三.Node.js安装与配置好啦今天到这了,希望帮到你!!!一.Vue路由1.1定义Vue路由是指使用VueRouter插件来管理前端应用程序的导航和页面路由的过程。它允许你在单页面应用程序(SPA)中定义不同的路由路径,并将

热文推荐