栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【刷题篇】最长回文子序列

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【刷题篇】最长回文子序列

目录
  • 一、题目
  • 二、题解
    • 2.1 方法一 :求该字符串与它的逆序字符串的最长公共子序列
    • 2.2 方法二:暴力递归
    • 2.3 方法三:动态规划

一、题目

OJ链接

二、题解 2.1 方法一 :求该字符串与它的逆序字符串的最长公共子序列

一个字符串的最长回文序列就是:
该字符串与它的逆序字符串的最长公共子序列
因为我们之前写过求两个字符串的最长公共子序列的题目

具体可见:

最长公共子序列

2.2 方法二:暴力递归

应用范围尝试模型解题(讨论一个范围的开头和结尾的可能性)

递归函数:

递归函数的含义:只考虑字符串str,从L到R位置的最长回文子序列的长度
终止条件:

L== R时,只剩下一个字符,一个字符是回文序列,长度是1,return 1; L==
R-1时,说明只剩下两个字符,如果这两个字符串相等,则构成回文序列,长度是2,如果不相等,最长的回文子序列长度就是1;

普遍情况:

考虑str[L…R]这个范围上最长回文子序列的可能性 (1)最长回文子序列既不以L开头,也不以R结尾
(2)最长回文子序列以L开头,不以R结尾 (3)最长回文子序列不以L开头,但以R结尾 (4)最长回文子序列以L开头,以R结尾

既然递归函数的含义是求L到R范围上的最长回文子序列长度,那么主函数上就应该这样调用

源码:

public static int f1(char[] str,int L,int R){
    if(L==R){
        return 1;
    }
    if(L==R-1){
        return str[L]==str[R-1]?2:1;
    }
    int p1=f1(str,L+1,R-1);
    int p2=f1(str, L+1, R);
    int p3=f1(str,L,R-1);
    int p4=str[L]==str[R]?2+f1(str, L+1, R-1):0;
    return  Math.max(Math.max(p1,p2),Math.max(p3,p4));
}
    public static int longestPalindromeSubseq1(String s) {
        if(s==null||s.length()==0){
            return 0;
        }
       char[] str=s.toCharArray();
        return f1(str,0,str.length-1);
    }
2.3 方法三:动态规划

思路:
根据方法二中的递归函数填表格

源码:

 public static int longestPalindromeSubseq2(String s) {
        if(s==null||s.length()==0){
            return 0;
        }
        char[] str=s.toCharArray();
        int N=str.length;
        int[][] dp=new int[N][N];
        dp[N-1][N-1]=1;
        for (int i = 0; i 
            dp[i][i]=1;
            dp[i][i+1]=str[i]==str[i+1] ? 2 : 1;
        }
        for (int L =N-3; L >=0; L--) {
            for (int R = L+2; R < N; R++) {
                int p1=dp[L+1][R-1];
                int p2=dp[L+1][R]; 
                int p3=dp[L][R-1];
                int p4=str[L]==str[R]?2+dp[L+1][R-1]:0;
               dp[L][R]= Math.max(Math.max(p1,p2),Math.max(p3,p4));
            }

        }
       return dp[0][N-1];
    }

优化:对方法法优化

  public static int longestPalindromeSubseq2(String s) {
        if(s==null||s.length()==0){
            return 0;
        }
        char[] str=s.toCharArray();
        int N=str.length;
        int[][] dp=new int[N][N];
        dp[N-1][N-1]=1;
        for (int i = 0; i 
            dp[i][i]=1;
            dp[i][i+1]=str[i]==str[i+1] ? 2 : 1;
        }
        for (int L =N-3; L >=0; L--) {
            for (int R = L+2; R < N; R++) {
                int p1=dp[L+1][R-1];
                int p2=dp[L+1][R];
                int p3=dp[L][R-1];
                int p4=str[L]==str[R]?2+dp[L+1][R-1]:0;
               dp[L][R]= Math.max(Math.max(p1,p2),Math.max(p3,p4));
            }

        }
       return dp[0][N-1];
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/893403.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号