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 群,

我们,

一起进步!
在这里插入图片描述

在这里插入图片描述

发布了25 篇原创文章 · 获赞 36 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/DreamLi1314/article/details/103332880