力扣第516题 最长回文子序列 c++ 动态规划 附Java代码 注释版

编程入门 行业动态 更新时间:2024-10-23 11:19:15

力扣第516题 最长<a href=https://www.elefans.com/category/jswz/34/1769494.html style=回文子序列 c++ 动态规划 附Java代码 注释版"/>

力扣第516题 最长回文子序列 c++ 动态规划 附Java代码 注释版

题目

516. 最长回文子序列

中等

相关标签

字符串   动态规划

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

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

示例 1:

输入:s = "bbbab"
输出:4
解释:一个可能的最长回文子序列为 "bbbb" 。

示例 2:

输入:s = "cbbd"
输出:2
解释:一个可能的最长回文子序列为 "bb" 。

提示:

  • 1 <= s.length <= 1000
  • s 仅由小写英文字母组成

思路和解题方法

  1.  首先,我们使用一个二维数组dp来存储子问题的解,其中dp[i][j]表示字符串s在位置i到位置j范围内的最长回文子序列的长度。
  2. 然后,我们初始化对角线上的值为1,表示单个字符本身就是一个回文子序列。
  3. 接下来,我们从字符串尾部开始向前遍历,在每个位置i和j之间进行计算。如果s[i]等于s[j],则s[i:j]范围内的最长回文子序列长度为s[i+1:j-1]范围内的最长回文子序列长度加2;如果s[i]不等于s[j],则s[i:j]范围内的最长回文子序列长度为s[i+1:j]和s[i:j-1]中的较大值。
  4. 最终,返回dp[0][s.size() - 1],即整个字符串的最长回文子序列长度。

打印的dp数组 

  a  b  c   b   a

复杂度

        时间复杂度:

                O(n*n)

        时间复杂度是O(n^2),其中n为输入字符串s的长度。这是因为我们使用了一个二维数组dp来存储子问题的解,然后使用两层嵌套的循环来填充这个数组,每次循环都需要考虑当前字符以及其之前的所有字符,因此时间复杂度为O(n^2)。

        空间复杂度

                O(n*n)

        空间复杂度也是O(n^2),因为我们使用了一个二维数组dp来存储子问题的解,其大小为n*n。

c++ 代码

class Solution {
public:int longestPalindromeSubseq(string s) {// 创建二维数组dp来存储子问题的解,dp[i][j]表示s[i:j]范围内的最长回文子序列长度vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));// 初始化对角线上的值为1,即单个字符本身就是一个回文子序列for (int i = 0; i < s.size(); i++) {dp[i][i] = 1;}// 从字符串尾部开始遍历for (int i = s.size() - 1; i >= 0; i--) {// 从当前字符向后遍历for (int j = i + 1; j < s.size(); j++) {if (s[i] == s[j]) {// 如果s[i]等于s[j],则s[i:j]范围内的最长回文子序列长度为s[i+1:j-1]范围内的最长回文子序列长度加2dp[i][j] = dp[i + 1][j - 1] + 2;} else {// 如果s[i]不等于s[j],则s[i:j]范围内的最长回文子序列长度为s[i+1:j]和s[i:j-1]中的较大值dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);}}}// 返回整个字符串的最长回文子序列长度return dp[0][s.size() - 1];}
};

Java代码

  • 首先,我们定义了一个二维数组dp来存储子问题的解,其中dp[i][j]表示字符串s在位置i到位置j范围内的最长回文子序列的长度。
  • 然后,我们从字符串尾部开始向前遍历,确保不漏掉任何情况。在此过程中,我们对dp数组进行初始化,并且通过动态规划的方法逐步填充dp数组。
  • 最后,返回dp[0][len - 1],即整个字符串的最长回文子序列长度。
public class Solution {public int longestPalindromeSubseq(String s) {int len = s.length();int[][] dp = new int[len + 1][len + 1];  // 创建二维数组dp来存储子问题的解,dp[i][j]表示s[i:j]范围内的最长回文子序列长度for (int i = len - 1; i >= 0; i--) {  // 从后往前遍历,保证情况不漏dp[i][i] = 1;  // 初始化对角线上的值为1,即单个字符本身就是一个回文子序列for (int j = i + 1; j < len; j++) {if (s.charAt(i) == s.charAt(j)) {dp[i][j] = dp[i + 1][j - 1] + 2;  // 如果s[i]等于s[j],则s[i:j]范围内的最长回文子序列长度为s[i+1:j-1]范围内的最长回文子序列长度加2} else {dp[i][j] = Math.max(dp[i + 1][j], Math.max(dp[i][j], dp[i][j - 1]));  // 如果s[i]不等于s[j],则s[i:j]范围内的最长回文子序列长度为s[i+1:j]和s[i:j-1]中的较大值}}}return dp[0][len - 1];  // 返回整个字符串的最长回文子序列长度}
}

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

更多推荐

力扣第516题 最长回文子序列 c++ 动态规划 附Java代码 注释版

本文发布于:2023-11-15 03:06:27,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1592660.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:回文   注释   序列   最长   代码

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!