LCS 最大公共序列算法

1.基本概念:
什么是最长公共子序列呢?
举个简单的例子吧,一个数列S,若分别是两个或多个已知序列的子序列,且是所有符合条件序列中最长的,则S称为已知序列的最长公共子序列。

最长公共子串(Longest Common Substirng)和最长公共子序列(Longest Common Subsequence,LCS)的区别为:子串是串的一个连续的部分,子序列则是从不改变序列的顺序,而从序列中去掉任意的元素而获得新的序列;也就是说,子串中字符的位置必须是连续的,子序列则可以不必连续。


2.动态规划求解最大公共子序列

LCS最大公共序列算法总结:

1、用矩阵来查找的算法,就是把两个队列用整形矩阵表示, 相同的为1, 不同的为0, 然后求最大对角线,优化是优化了很多, 不过求最大对角线也不省心。

2、再次优化了算法,就是相同的不是用1表示, 而是数字叠加,这样再找最大对角线的时候,就比较简答了,时间复杂度也降到了 O(mn)+O(m+n) 如下图:

这里写图片描述
代码实现要遵从两条原则:

1、字符相同,则指向左上,并在左上的基础上加1赋给当前位置,记录

2、字符不同,则指向左边或者上边较大的那个,并将该值赋给当前位置,记录


3.案例驱动

Mean:
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?输出需要删除的字符个数。

analyse:
对于这题来说,插入字符和删除字符使其成为回文串,答案是一样的.
1.首先求s的反串rs,
2.然后对s和rs求最长公共子序列,要删除的字符个数就是LCS.
其中:采用矩阵记录两个字符串中的所有位置的两个字符之间的匹配情况,若字符相同,则指向左上并加1赋给当前位置,记录;若字符不同,则指向左边或者上边较大的一个,并将该值赋给当前位置,记录。

Time complexity: O(N^2)



import java.util.Scanner;

public class Main {

    public static void main(String[] args){

        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){

            String readstr = sc.nextLine();
            char[] readchar1 =readstr.toCharArray();
            char[] readchar2 = new char[readchar1.length];
            int index = 0;
            for(int i=readchar1.length-1; i>-1 ; i--)
            {
                readchar2[index] = readchar1[i];
                index++;
            }

            System.out.println(readstr.length()-getLCS(readchar1,readchar2));
        }
    }
    static int getLCS(char[] readChar1,char[] readChar2){
        int len = readChar1.length;
        int dp[][] = new int[1001][1001]; 
        for(int i=0;i<len;++i)
           {
               for(int j=0;j<len;++j)
               {
                   if(readChar1[i]==readChar2[j])
                       dp[i+1][j+1]=dp[i][j]+1;
                   else dp[i+1][j+1]=Math.max(dp[i][j+1],dp[i+1][j]);
               }
           }
           return dp[len][len];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值