首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[算尽天下系列第7期]LeetCode·516·最长回文子序列

[算尽天下系列第7期]LeetCode·516·最长回文子序列

作者头像
凝神长老
发布于 2020-04-17 09:14:04
发布于 2020-04-17 09:14:04
30100
代码可运行
举报
运行总次数:0
代码可运行

LeetCode 516 最长回文子序列

题目描述

给定一个字符串 s,找到其中最长的回文子序列。可以假设 s 的最大长度为 1000。

样例

样例输入1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bbbab

样例输出1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
4

样例解释1

一个可能的最长回文子序列为 bbbb

样例输入2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cbbd

样例输出2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2

样例解释2

一个可能的最长回文子序列为 bb

算法与数据结构

动态规划

题解

再多看几道动态规划的题目,长老就要和大家分享微软、字节跳动等大公司笔试中的动态规划真题啦,所以大家一定要认真消化这几题哦。

最长回文子序列也是动态规划中的经典题目,这次不再是线性规划了,而是二维矩阵,不过理解起来也很容易。

回顾线性规划中,我们往往定义 dp[i] 为到 i 为止符合题目要求的解的值,而在二维动态规划中,我们往往定义 dp[i][j] 表示从 i 到 j 这一段中符合题目要求的解的值。

例如对于这道题,我们定义 dp[i][j] 表示字符串从 i 到 j 的子串中,最长子序列的长度。最终,dp[0][n - 1] 就是答案。

那么,状态转移呢?

为了得到 dp[i][j],我们可以考察 s[i]s[j],如果这两个位置上的字符是一样的,那么显然,dp[i][j] = dp[i + 1][j - 1] + 2

如果这两个位置上的字符是不一样,那么,取 dp[i + 1][j]dp[i][j - 1] 中较大的即可。

最后考虑初始条件,初始条件就是当长度为 1 时,自然成为回文序列,于是,dp[i][i] = 1 对任意的 i 成立。

但是在写代码的时候,我们需要注意,这里数组下标的循环并不能简单从 1 循环到 n:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (int i = 0; i < n; i++) {
	for (int j = i + 1; j < n; j++) {
		// TODO
	}
}

通过简单比对样例输入输出可以很容易发现,状态转移并不是随着下标推进的,而是随着下标之间的距离(即 i 和 j 之间的距离)推进的:我们首先得到了 dp[i][i] 的值,都等于 1,也就是所有长度为 1 的子串,我们得到了它的最长回文子序列的长度,下面应该去计算所有长度为 2 的子串,再长度为 3 的子串……只有这样,我们比较 s[i]s[j] 才是有意义的。

所以,一种常见的技巧就是以跨度 len 为外层循环,以下标 i 为内层循环,在循环内计算下标 j

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (int len = 1; len <= length; len++) {
	for (int i = 0; i + len - 1 < length; i++) {
		int j = i + len - 1;
		// TODO
	}
}

完整代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int length = s.length();
int[][] dp = new int[length][length];
for (int len = 1; len <= length; len++) {
    for (int i = 0; i + len - 1 < length; i++) {
        int j = i + len - 1;
        if (i == j) {
            dp[i][j] = 1;
        } else {
            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]);
            }
        }
    }
}
return dp[0][length - 1];
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 凝神长老和他的朋友们 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
​LeetCode刷题实战516:最长回文子序列
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
程序员小猿
2022/03/03
2670
​LeetCode刷题实战516:最长回文子序列
Leetcode 516. 最长回文子序列
输入:"bbbab" 输出:4 解释: 一个可能的最长回文子序列为 "bbbb"。
zhipingChen
2019/07/03
1.1K0
Leetcode 516. 最长回文子序列
动态规划:最长回文子序列
题目链接:https://leetcode-cn.com/problems/longest-palindromic-subsequence/
代码随想录
2021/04/23
1.1K0
子序列解题模板:最长回文子序列
首先,子序列问题本身就相对子串、子数组更困难一些,因为前者是不连续的序列,而后两者是连续的,就算穷举都不容易,更别说求解相关的算法问题了。
labuladong
2021/09/23
5130
回文串「建议收藏」
统计字符出现的次数即可,双数才能构成回文。因为允许中间一个数单独出现,比如“abcba”,所以如果最后有字母落单,总长度可以加 1。首先将字符串转变为字符数组。然后遍历该数组,判断对应字符是否在hashset中,如果不在就加进去,如果在就让count++,然后移除该字符!这样就能找到出现次数为双数的字符个数。
全栈程序员站长
2022/11/01
4260
Leetcode 516. Longest Palindromic Subsequence
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.   找到一个字符串的最长回文子序列,这里注意回文子串和回文序列的区别。子序列不要求连续,子串(substring)是要求连续的。leetcode 5. Longest Palindromic Substring就是求连续子串的。   思路很简答,其实最长回文子序列就是字符串本身和其翻转字符串的最长公共子序列,求两个字符串的最长公共子序列其实是动态规划入门题目。 题解代码如下。
xindoo
2021/01/22
3200
leetcode516. Longest Palindromic Subsequence
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.
眯眯眼的猫头鹰
2020/05/11
4810
LeetCode 0005. 最长回文子串[动态规划详解]
本题可以使用动态规划来做,但是直接遍历每个字符串/每两个字符串空隙,向左右延展求最长回文子串也是可以的,思路比较暴力直接,详情见代码 1。
Yano_nankai
2021/03/02
4130
LeetCode 0005. 最长回文子串[动态规划详解]
【力扣刷题】5. 最长回文子串
根据回文串的定义,正着和反着读一样,那我们是不是把原来的字符串倒置了,然后找最长的公共子串就可以了。例如 S = "caba" ,S = "abac",最长公共子串是 "aba",所以原字符串的最长回文串就是 "aba"。
jayjay
2022/11/02
2560
【力扣刷题】5. 最长回文子串
【字符串】最长回文子串 ( 动态规划算法 ) ★
" 回文串 ( Palindrome ) " 是 正反都一样的字符串 , abccba , 001100 等字符串 ;
韩曙亮
2023/03/29
7540
【字符串】最长回文子串 ( 动态规划算法 ) ★
005. 最长回文子串 | Leetcode题解
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
苏南
2020/12/16
5290
005. 最长回文子串 | Leetcode题解
多种思路深度剖析经典面试题---最长回文子串
大家好,我是程序员小熊,来自大厂的程序猿。最长回文子串是面试中常考的题目,尤其是一些互联网大厂,像亚马逊、微软、脸书、字节和腾讯等都考过这道题。
程序员小熊
2021/05/17
6960
多种思路深度剖析经典面试题---最长回文子串
动态规划:最长回文子串 & 最长回文子序列
所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如 “a”、“aba”、“abba”。
全栈程序员站长
2022/08/11
9060
【算法专题】动态规划之回文子串问题
题目:给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
YoungMLet
2024/03/01
2100
搞定大厂算法面试之leetcode精讲20.字符串
方法1.截取字符串,循环字符串,遇到#就截掉最后一个字符,循环完毕之后,最后比较两个去除掉#退格之后的字符串是否相等,时间复杂度O(m+n),m、n是两个字符串的长度。空间复杂度O(1)
全栈潇晨
2021/12/04
7550
常见动态规划类型--案例详解
动态规划的核心思想是将原问题拆解成子问题,并通过解决子问题来求解原问题。为了避免重复计算,动态规划会将子问题的解进行存储,在需要的时候直接获取,从而提高效率。
刺槐儿
2023/11/17
7710
LeetCode【5】-- 最长回文子串(马拉车算法)
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-palindromic-substring,著作权归领扣网络所有。
秦怀杂货店
2022/02/15
3330
LeetCode【5】-- 最长回文子串(马拉车算法)
【算法】几道常见的算法字符串算法题
谈到字符串问题,不得不提的就是 KMP 算法,它是用来解决字符串查找的问题,可以在一个字符串(S)中查找一个子串(W)出现的位置。KMP 算法把字符匹配的时间复杂度缩小到 O(m+n) ,而空间复杂度也只有O(m)。因为“暴力搜索”的方法会反复回溯主串,导致效率低下,而KMP算法可以利用已经部分匹配这个有效信息,保持主串上的指针不回溯,通过修改子串的指针,让模式串尽量地移动到有效的位置。
周三不加班
2019/09/04
9320
【算法】几道常见的算法字符串算法题
多种思路秒杀经典面试题最长回文子串
大家好,我是程序员小熊,来自大厂的程序猿。最长回文子串是面试中常考的题目,尤其是一些互联网大厂,像亚马逊、微软、脸书、字节和腾讯等都考过这道题。
程序员小熊
2021/05/28
6790
多种思路秒杀经典面试题最长回文子串
LeetCode-5-最长回文字串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
benym
2022/07/14
2040
推荐阅读
相关推荐
​LeetCode刷题实战516:最长回文子序列
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档