前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >leetcode516. Longest Palindromic Subsequence

leetcode516. Longest Palindromic Subsequence

作者头像
眯眯眼的猫头鹰
发布2020-05-11 17:33:36
4290
发布2020-05-11 17:33:36
举报

题目要求

Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.

Example 1: Input: "bbbab" Output: 4 One possible longest palindromic subsequence is "bbbb".

Example 2: Input: "cbbd" Output: 2 One possible longest palindromic subsequence is "bb".

现有一个字符串s,要求找出最长的回文子序列的长度。这里要注意,子序列和子字符串不同,允许序列中的元素不是连续的。

思路和代码

这是一道典型的动态规划的题目,假设我们已经知道数组中任意长度为i的子字符串的最长回文子序列长度,则可以推导出长度为i+1的子字符串的最长回文子序列长度。推导过程如下:

首先假设tmp[j-i][j]记录了[j-i,j]子字符串中的最长回文子序列长度,则对于[j-i-1, j]我们可知一定会有两种情况

  1. s[j-i-1]==s[j] 则最大的子序列长度等于tmp[j-i][j-1]+2,即等于[j-i,j-1]这个子字符串中的最大子序列长度加上2
  2. s[j-i-1]!=s[j],则最大的子序列长度等于Math.max(tmp[j-i][j], tmp[j-i-1][j-1]),即等于[j-i,j][j-i-1,j-1]两个子字符串中能够找出来的最大子序列长度。

代码如下:

代码语言:javascript
复制
    public int longestPalindromeSubseq(String s) {
        int[][] tmp = new int[s.length()][s.length()];
        for(int i = 0 ; i<s.length() ; i++) {
            for(int j = 0 ; j+i<s.length() ; j++) {
                if (i==0) {
                    tmp[j][j+i] = 1;
                }else if (s.charAt(j) == s.charAt(j+i)) {
                    if (i==1) {
                        tmp[j][j+i]  = 2;
                    } else {
                        tmp[j][j+i]  = 2 + tmp[j+1][j+i-1];
                    }
                }else {
                    tmp[j][j+i] = Math.max(tmp[j][j+i-1], tmp[j+1][j+i]);
                }
            }
        }
        return tmp[0][s.length()-1];
    }

一个空间复杂度的优化在于,我们只用一个一维数组存储以下标i为结尾的任意长度的子字符串的最长子序列,其中dp[j]存储的是[j,i]子字符串的最长子序列。那么,当计算下标为i+1结尾的任意长度的子字符串的最长子序列时,同样可以推导出来。

代码语言:javascript
复制
    public int longestPalindromeSubseq2(String s) {
        char[] str = s.toCharArray();
        //dp[j]表示以j为开头的的[j~i]的最长回数子序列长度,当i=s.length-1时,则dp中存储了所有以j为开始最远到i的最长回数子序列长度
        int[] dp = new int[str.length];
        int max = 0;

        for (int i=0; i<dp.length; i++) {
            dp[i] = 1;

            int maxSoFar = 0;
            for (int j=i-1; j>=0; j--) {
                int prev = dp[j];
                if (str[i] == str[j]) {
                    dp[j] = maxSoFar + 2;
                }
                maxSoFar = Math.max(prev, maxSoFar);
            }
        }

        for (int i : dp){
            max = Math.max(max, i);
        }
        return max;
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目要求
  • 思路和代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档