Source: Link:
Disclaimer: If I violate anyone's rights, please contact me and I will delete it.
Welcome experts to spray me
Article Directory
The longest common substring title description
Given two strings str1 and str2, output the longest common substring of the two strings. If the longest common substring is empty, output -1.
Example 1
Input "1AB2345CD", "12345EF"
returns the value "2345"
The longest common substring code:
import java.util.*;
public class Solution {
/**
* longest common substring
* @param str1 string字符串 the string
* @param str2 string字符串 the string
* @return string字符串
*/
public String LCS (String str1, String str2) {
if(str1 == null || str2 == null || str1.equals("") || str2.equals("")){
return "-1";
}
int indexMax = 0;
int maxLen = 0;
int m = str1.length();
int n = str2.length();
//dp[i][j]代表 str1[0~i-1]和str2[0~j-1] 的最长公共子串的长度
int[][] dp = new int[m][n];
for(int i = 0; i < m; ++ i){
for(int j = 0; j < n; ++j){
if(str1.charAt(i) == str2.charAt(j)){
if(i == 0 || j == 0){
dp[i][j] = 1;
}else{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
}//else 是str1[i]!=str2[j]的情况,这种情况下dp[i][j]=0,由于初始化已经将其设置为0,所以这里不再写。
//处理完dp[i][j]之后,查看一下是否需要记录下来
if(maxLen < dp[i][j]){
maxLen = dp[i][j]; //记录下最长公共子串的长度
indexMax = i; //记录下出现“最长公共子串”时的末尾字符的位置
}
}
}
if(maxLen == 0) return "-1";
//字符串截取的长度有(end-start+1) = maxLen, 那么start = indexMax +1-maxLen
// maxLen即为所截取的字符串的长度。
return str1.substring(indexMax - maxLen + 1 , indexMax + 1);
}
}
The longest common subsequence title description
Given two strings str1 and str2, output the longest common subsequence of a string. If the longest common subsequence is empty, -1 is output.
Example 1
Input "1A2C3D4B56", "B1D23CA45B6A" and the
return value "123456"
shows that "123456" and "12C4B6" are the longest common subsequences, and any one is output.
Longest common subsequence code
import java.util.*;
public class Solution {
/**
* longest common subsequence
* @param s1 string字符串 the string
* @param s2 string字符串 the string
* @return string字符串
*/
public String LCS (String s1, String s2) {
// write code here
int str1Len = s1.length();
int str2Len = s2.length();
int[][] cLenNUm = new int[s1.length() + 1][s2.length() + 1];//默认赋值,[0][?],[?][0]默认两侧皆0,类似公式中0的场景
//构造一个LCS长度数组
for (int i = 1; i <= str1Len; i++) {
for (int j = 1; j <= str2Len; j++) {
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {//对应公式第二条相等
cLenNUm[i][j] = cLenNUm[i - 1][j - 1] + 1;
} else {//对应公式第三条不相等
cLenNUm[i][j] = Math.max(cLenNUm[i][j - 1], cLenNUm[i - 1][j]);
}
}
}
//反推结果
int i = str1Len;
int j = str2Len;
StringBuffer sb = new StringBuffer();//作为结果
while (i > 0 && j > 0) {//这里其实处理了i=0,j=0的,对应公式0的反推场景
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {//反推公式中不相等的场景
//该值一定是被选取到的,根据之前的公式,知道两条字符串的下标都前进一位
sb.append(s1.charAt(i - 1));
i--;
j--;
} else {//对应公式中不相等的反推场景
if (cLenNUm[i][j - 1] > cLenNUm[i - 1][j]) {//找大的那个方向,此处是左边大于上面,则该处的结果是来自左边
j--;
} else if (cLenNUm[i][j - 1] < cLenNUm[i - 1][j]) {
i--;
} else if (cLenNUm[i][j - 1] == cLenNUm[i - 1][j]) {
//对于有分支的可能时,我们选取单方向
j--; //此结果对于结果1所选取方向,str1的下标左移一位.替换为j--,则结果对应与结果2选取的方向
}
}
}
//由于是从后往前加入字符的,需要反转才能得到正确结果
return sb.reverse().toString();
}
}
Both questions are dynamic programming
The longest common substring: the letters in the substring required here areThere is no space between other characters
int[][] dp = new int[len1+1][len2+1];
dp[0][0] = 0;
int maxlen = Integer.MIN_VALUE, indexmax = -1;
for(int i=0;i<len1;++i){
for(int j=0;j<len2;++j){
if(str1.charAt(i) == str2.charAt(j)){
if(i == 0 ||j == 0) dp[i][j] = 1;
else dp[i][j] = dp[i-1][j-1] + 1;
}
if(maxlen < dp[i][j]){
maxlen = dp[i][j];
indexmax = i;
}
}
}
The longest subsequence, here in the common substringCan space other characters
int[][] dp = new int[len1+1][len2+1];
dp[0][0] = 0;
for(int i=1;i<=len1;++i){
for(int j=1;j<=len2;++j){
if(s1.charAt(i-1) == s2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1]+1;
}else{
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
}