最長公共子序列問題解析

## 問題解讀

最長公共子序列問題,就是找出兩個字符串中,存在的最長的子序列java

什麼是子序列呢?
子序列不一樣於公共子串,子串是每一個字符連續的,子序列不必定要連續,見下例 [example]app

[example]: 好比 mStringA = "abc11google11111111", mStringB = "1111111141615" 這兩個字符串
那麼,mStringA 和 mStringB 的最長公共子序列就是 1111111111post


如何求解

咱們對於問題進行白話講解,假如如今有兩個字符串,而且有兩個指針,這每一個指針,各自指向這兩個字符串,咱們把這兩個指針設置爲 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")
        );
    }
}

掘金地址

相關文章
相關標籤/搜索