LCS 獲取兩個字符串的最長公共連續子串

在這裏插入圖片描述

  • 上一篇 LeetCode 我們用暴力法求解的最長迴文子序列的問題, 但是很可惜我們的時間複雜度太高, 不被接受, 今天我們本着另一個思想再次求解此問題, 但是由於新的算法需要獲取兩個字符串換的公共子串, 因此, 我們首先介紹一個新的問題:

獲取兩個字符串的最長公共連續子串.
例如:
輸入:
“abcfg” 與 “kmlozazui”
“aaaaa” 與 “aaaaaaaaa”
“abcdefedcba” 與 “abcdefedcba”

輸出:
“a”
“aaaaa”
“abcdefedcba”

暴力求解法就不介紹了(以後暴力求解法也不會出現在博人中, 除非有必要 ), 大家都能想到, 這裏介紹一種動態規劃 DP 算法求解最長公共子串.
在這裏插入圖片描述

  • 首先根據 str1 和 str2 初始化一個表 rc[str1.length][str2.length], 其初始值值均爲 0;
  • 遍歷每一個行和列, 如果 str1[i] == str2[j], 那麼 rc[i][j] = rc[i - 1][j - 1] + 1. 這樣最長公共連續子串就是 rc 中值最大的單元格所對應的子串.

也可以如果 str1[i] == str2[j], 那麼 rc[i][j] = 1. 這樣最長公共連續子串就是 rc 中值爲 1 且長度最長的對角連線所對應的子串.


Talk is cheap, show me the code…


package com.jackli.solution;

/**
* @Description: LCS: 獲取一個字符中的最長公共連續子串.
* @Warning:
* @Author: Jack Li
* @Package: question005 - LongestSubString
* @Date: Nov 30, 2019 11:39:17 PM
* @Version: 1.0.0
* @TimeComplexity: Required[*] ---- Current[O(n^2)]
* @ExecuteResult: Success!
* @Status: Accepted
 */
public class LongestSubString {
	public static void main(String[] args) {
		System.out.println(longestSubstring("", null));
		System.out.println(longestSubstring("", ""));
		System.out.println(longestSubstring("abc", "defg"));
		System.out.println(longestSubstring("abcfg", "kmlozazui"));
		System.out.println(longestSubstring("aaaaa", "aaaaaaaaa"));
		System.out.println(longestSubstring("abcdefedcba", "abcdefedcba"));
	}
	
	/**
	 * @Description: 定義一個以 str1 爲行, 以 str2 爲 列的
	 * @Warning: 
	 * @Author: Jack Li
	 * @Date: Nov 30, 2019 11:56:16 PM
	 * @Version: 1.0.0
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static String longestSubstring(String str1, String str2) {
		if(str1 == null || str1.isEmpty() || str2 == null || str2.isEmpty()) {
			return null;
		}
		
		String result = null;
		
		// 初始化一個表用於記錄 str1 和 str2 的相同字符的座標與長度
		int[][] rc = new int[str1.length()][str2.length()];
		int leftTop;
		
		int subLength = 0, endIndexByStr1 = 0;
		
		for(int i = 0; i < str1.length(); i++) {
			for(int j = 0; j < str2.length(); j++) {
				if(str1.charAt(i) == str2.charAt(j)) {
					// 獲取左上角的值
					leftTop = 0;
					
					if(i > 0 && j > 0) {
						leftTop = rc[i - 1][j - 1];
					}

					rc[i][j] = leftTop + 1;
					
					if(rc[i][j] > subLength) {
						subLength = rc[i][j];
						endIndexByStr1 = i;
					}
				}
			}
		}
		
		// 獲取最長子序列
		if(subLength > 0) {
			result = str1.substring(endIndexByStr1 - subLength + 1, endIndexByStr1 + 1);
		}
		
		return result;
	}
}

每文一騷

We’re in the fight of our lives.
我們都在生命中奮鬥着.

沒過癮?

關注我獲取更多技術乾貨

————————————

掃一掃關注公衆號, 加入 QQ 羣,

我們,

一起進步!
在這裏插入圖片描述

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章