美文网首页
最长公共子序列问题解析

最长公共子序列问题解析

作者: newcaoguo | 来源:发表于2018-11-08 18:17 被阅读5次

问题解读


最长公共子序列问题,就是找出两个字符串中,存在的最长的子序列

什么是子序列呢?
子序列不同于公共子串,子串是每个字符连续的,子序列不一定要连续,见下例 [example]

[example]: 比如 mStringA = "abc11google11111111", mStringB = "1111111141615" 这两个字符串
那么,mStringA 和 mStringB 的最长公共子序列就是 1111111111


如何求解

我们对于问题进行白话讲解,假如现在有两个字符串,并且有两个指针,这每个指针,各自指向这两个字符串,我们把这两个指针设置为 i 和 j,即,i 指向 mStringA 的某个字符,j 指向 mStringB 的某个字符,那么,此时的状态方程为 f(i, j),表示 i 指向 mStringA 的某个字符和 j 指向 mStringB 的某个字符的情况

  • 当两个指针指向的字符相等时,那么代表这是一个成功的状态,此时,状态记为f(i + 1, j + 1) + 1,表示 i 和 j 两个指针可以同时向右方移动
  • 当两个指针指向的字符不相等的试试,那么代表这是一个待完成的状态,此时,状态记为 f(i + 1, j)f(i, j + 1)

Talk is cheap, show me code ~~~

package com.company;

import org.junit.Test;

public class LongestCommonSequence {
    // 用来存储匹配过程中存取的记录
    public StringBuilder sb = new StringBuilder();
    /* 
    * 获得最长公共子序列的方法
    * 传入两个参数,即为需要处理的字符串
    * 核心实现方法在 longestCommonSequence(...)
    */
    public String getLongestCommonSequence(String mStringA, String mStringB) {
        // 1. 拿到最长公共子序列的长度
        int strLength = longestCommonSequence(0, mStringA, 0, mStringB);
        // 2. 将 StringBuilder 转为 String 类
        String mString = new String(sb);
        // 3. 对记录进行裁剪,最后的 strLength 个字符,是最终的结果
        return mString.substring(
                strLength - longestCommonSequence(0, mStringA, 0, mStringB),
                strLength);
    }

    // 最长公共子序列的实现方法
    public int longestCommonSequence(int i, String mStringA, int j, String mStringB) {
        // 1. 边界条件判断,当指针到头的时候,返回 0
        if (i == mStringA.length() || j == mStringB.length()) {
            return 0;
        }
        // 2. 当两个指针指向的字符相等的时候,这是状态方程为:f(i + 1, j + 1) + 1
        if (mStringA.charAt(i) == mStringB.charAt(j)) {
            sb.append(mStringA.charAt(i));
            return longestCommonSequence(i + 1, mStringA, j + 1, mStringB) + 1;
        } else { // 3. 当两个指针指向的字符不相等的时候,这是状态方程为:f(i + 1, j) 或者 f(i, j + 1)
            return Math.max(longestCommonSequence(i + 1, mStringA, j, mStringB),
                    longestCommonSequence(i, mStringA, j + 1, mStringB));
        }
    }
    
    // 测试方法
    @Test
    public void test() {
        // 1111111111
        System.out.println(
                getLongestCommonSequence("abc11google11111111",
                        "1111111141615")
        );
    }
}

掘金地址

相关文章

  • 算法(04)动态规划

    零钱问题 背包问题 最长公共子序列 最长公共子串 最长上升子序列 最大连续子序列和

  • LCS问题

    LCS问题包括最长公共子序列和最长公共子串,其中,最长公共子串要求必须连续。 对于二者的求解方式 最长公共子序列:...

  • 公共子序列问题

    最长公共子序列 最长上升子序列 最长公共上升子序列

  • 最长公共子序列和最长公共子串

    最长公共子序列和最长公共子串区别 最长公共子串(Longest CommonSubstring)和最长公共子序列(...

  • 序列比对(二十四)——最长公共子序列

    原创:hxj7 本文介绍如何求解两个字符串的最长公共子序列。 最长公共子序列问题 前文《序列比对(23)最长公共子...

  • lintcode 最长公共子序列

    给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。说明最长公共子序列的定义: 最长公共子序列问题是在...

  • 最长公共子序列问题解析

    问题解读 最长公共子序列问题,就是找出两个字符串中,存在的最长的子序列 什么是子序列呢?子序列不同于公共子串,子串...

  • 动态规划 最长公共子串

    核心思路和最长公共子序列一样 区别在于子串必须连续 可以先看我之前这篇文章最长公共子序列问题总结 最长公共子串同样...

  • 动态规划常见面试题

    子序列类型编辑距离 最长递增子序列 最大子数组 最长公共子序列 背包问题0-1背包问题 子集背包问题 完全背包问题...

  • 最长公共子序列问题

    问题描述: 求两个字符序列的公共最长子序列。 最长公共子串 在回到子序列问题之前,先来了解一下子串的问题。例如,H...

网友评论

      本文标题:最长公共子序列问题解析

      本文链接:https://www.haomeiwen.com/subject/hhtgxqtx.html