leetcode 516. 最长回文子序列(JAVA)题解

这篇具有很好参考价值的文章主要介绍了leetcode 516. 最长回文子序列(JAVA)题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目链接https://leetcode.cn/problems/longest-palindromic-subsequence/description/?utm_source=LCUS&utm_medium=ip_redirect&utm_campaign=transfer2china

目录

题目描述:

暴力递归:

动态规划:


题目描述:

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

示例 1:

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

示例 2:

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

提示:

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

这道题的知识点是动态规划,可是如果直接从动态规划讲可能有点不容易理解。

所以本篇文章就是从暴力递归到动态规划

从题目中我们可以得出:本题找的是可以不连续的回文子串然后返回其最大序列的长度。

也就是说:

a2b42a

的最长回文子序列为:a2b2a或a242a 这两个都可以因为它们返回的都是5

暴力递归:

我们先写一个可以返回最长的回文子序列长度的函数:

//主函数
public int longestPalindromeSubseq(String s) {
        char[] str = s.toCharArray();
        return maxString(str, 0, str.length-1);
}

//假设该函数可以返回最长回文子序列的长度
public static int maxString(char[] str, int l, int r) {}

我们写的 maxString() 方法可以返回 str 字符串[l, r]区间的最长回文子序列的长度 。

通过分析可以得出以下结论:

两种特殊情况:

  • 首先我们可以得到当 l 和 r 相等就证明此时只有一个字符那么它的返回值就是 1
  • 如果传入的数组只有两个字符即 l + 1 == r 那么此时如果这两个字符相等就返回 2 ,如果不相等就返回 1

普遍情况:

  • 两边的字符不存在于最长的回文子序列中。例:a1221b    ->   1221;
  • 右边的字符不存在在于最长的回文子序列中。例:1221b    ->   1221;
  • 左边的字符不存在在于最长的回文子序列中。例:a1221    ->   1221;
  • 两边的字符存在于最长的回文子序列中。例:1w221    ->   1221。

 此时代码就可以这样写:

//主函数
public int longestPalindromeSubseq(String s) {
        char[] str = s.toCharArray();
        return maxString(str, 0, str.length-1);
}

//假设该函数可以返回最长回文子序列的长度
public static int maxString(char[] str, int l, int r) {
        //先判断两种特殊情况
        if (l == r){
            return 1;
        }
        if (l + 1 == r){
            return str[l] == str[r] ? 2 : 1;
        }
        //余下的四种情况
        int a1 = maxString(str, l + 1, r - 1);
        int a2 = maxString(str, l, r - 1);
        int a3 = maxString(str, l + 1, r);
        int a4 = str[l] == str[r] ? 2 + maxString(str, l + 1, r - 1) : 0;
        
        //因为题目要求返回最长序列长度  所以需要返回这四个的最大值
        return Math.max(Math.max(a1, a2), Math.max(a3, a4));
}

 此时我们可以提交以下:

leetcode 516. 最长回文子序列(JAVA)题解,开发语言,java,动态规划,算法

 虽然没通过但是从它的报错信息可以看出,我们的思路是没问题的。

动态规划:

我们有了递归版本后就可以根据它来写出动态规划版本了。

 因为在maxString() 方法中只有 l 和 r 是变量,而它们两个的取值范围都是 [0,str.length - 1] 

此时我们就可以通过创建一个二维数组将 l 和 r 所有情况都列举出来然后返回数组[0,str.length - 1] 下标的值就可以得出答案了。

我们先假设长度只有 5 ,那么我们就可以创建如下的二维数组 l 行,r 列

public static int maxString(char[] str, int l, int r) {

        int[][] arr = new int[str.length][str.length];
        
}

 leetcode 516. 最长回文子序列(JAVA)题解,开发语言,java,动态规划,算法

接下来的填表阶段就可以根据递归函数直接填(以“a1221”为例子): 

 leetcode 516. 最长回文子序列(JAVA)题解,开发语言,java,动态规划,算法

 leetcode 516. 最长回文子序列(JAVA)题解,开发语言,java,动态规划,算法

此时 [0, 4] 位置的值就是最终答案。 

 根据每个位置的关系就将递归优化成:

public static int maxString(char[] str, int l, int r) {

        int[][] arr = new int[str.length][str.length];
        //因为不存在l < r的情况所以下三角的空间不用
        for (int i = 0; i < str.length; i++) {
            if (i == 0){//填第一条对角线
                int j = 0;
                while(j < str.length) {
                    arr[j][j] = 1;
                    j++;
                }
            }else if (i == 1) {//填第二条斜线
                int j = 1;
                while(j < str.length) {
                    arr[j - 1][j] = (str[j - 1] == str[j]) ? 2 : 1;
                    j++;
                }
            }else {//其他
                int j = i;
                int k = 0;
                while(j < str.length){
                    int a1 = arr[k + 1][j - 1];
                    int a2 = arr[k][j - 1];
                    int a3 = arr[k + 1][j];
                    int a4 = str[k] == str[j] ? 2 + arr[k + 1][j - 1] : 0;
                    arr[k][j] = Math.max(Math.max(a1, a2), Math.max(a3, a4));
                    j++;
                    k++;
                }
            }

        }
        return arr[0][str.length-1];
}

此时再提交就过了。 

leetcode 516. 最长回文子序列(JAVA)题解,开发语言,java,动态规划,算法

 文章来源地址https://www.toymoban.com/news/detail-649060.html

到了这里,关于leetcode 516. 最长回文子序列(JAVA)题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 647.回文子串 516.最长回文子序列

    力扣题目链接(opens new window) 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。 示例 1: 输入:“abc” 输出:3 解释:三个回文子串: “a”, “b”, “c” 示例 2: 输入

    2024年01月19日
    浏览(35)
  • 算法刷题|647.回文子串、516.最长回文子序列

    题目:给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。 d

    2024年02月17日
    浏览(37)
  • Day 57|647. 回文子串| 516.最长回文子序列

    ● 647. 回文子串 ● 516.最长回文子序列 ● 动态规划总结篇 难

    2024年02月16日
    浏览(35)
  • 代码随想录 Day - 59|#647 回文字串|#516 最长回文子序列

    ● 647. 回文字串 ● 516. 最长回文子序列 给你一个字符串 s ,请你统计并返回这个字符串中回文子串的数目。 回文字符串是正着读和倒过来读一样的字符串。 子字符串是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成

    2024年02月07日
    浏览(32)
  • 【刷题1】LeetCode 131. 分割回文串 java题解

    2024: 刚开始做leetcode hot100,查阅自己以前写的题解专栏,发现没有这一题,于是加上。可能leetcode100更新了吧。我看现在leetcode100官网的题目已经是分好类的了,以前我的题解帖子是自己手动分类整理的。

    2024年02月19日
    浏览(30)
  • 【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)

    标签(题目类型):回文串、动态规划 原题:LeetCode 5 思路 Dynamic Programming(DP) 动态规划是一种将问题分解成子问题并分别计算的优化技术。对于回文子串,我们可以使用动态规划来解决。 对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后

    2024年04月14日
    浏览(53)
  • 最长子串和回文子串相关的算法题解

    中等 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s = “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: s = “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。 示

    2024年02月19日
    浏览(28)
  • 动态规划-最长的回文序列

    该题是lintcode上 667 · 最长的回文序列,该题的解题思路亦是参考了九章侯老师的解题思路给出。 给一字符串 s, 找出在 s 中的最长回文子序列的长度. 你可以假设 s 的最大长度为 1000. 输入: “bbbab” 输出: 4 解释: 一个可能的最长回文序列为 “bbbb” 输入: “bbbbb” 输出:

    2024年02月09日
    浏览(37)
  • leetcode300. 最长递增子序列(动态规划-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/longest-increasing-subsequence 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序

    2024年02月15日
    浏览(34)
  • leetcode1143. 最长公共子序列-动态规划(java)

    leetcode1143. 最长公共子序列 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/longest-common-subsequence 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串: 它是由原字

    2024年01月19日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包