对于两个字符串,请设计一个时间复杂度为O(m*n)的算法(这里的m和n为两串的长度),求出两串的最长公共子串的长度。这里的最长公共子串的定义为两个序列U1,U2,..Un和V1,V2,...Vn,其中Ui + 1 == Ui+1,Vi + 1 == Vi+1,同时Ui == Vi。
给定两个字符串A和B,同时给定两串的长度n和m。
测试样例:
"1AB2345CD",9,"12345EF",7
返回:4
对于两个字符串,请设计一个时间复杂度为O(m*n)的算法(这里的m和n为两串的长度),求出两串的最长公共子串的长度。这里的最长公共子串的定义为两个序列U1,U2,..Un和V1,V2,...Vn,其中Ui + 1 == Ui+1,Vi + 1 == Vi+1,同时Ui == Vi。
给定两个字符串A和B,同时给定两串的长度n和m。
"1AB2345CD",9,"12345EF",7
返回:4
import java.util.*;
public class LongestSubstring {
// 动态规划解决最长公共子串问题:
public int findLongest(String A, int n, String B, int m) {
if (A.length() == 0 || n == 0 || B.length() == 0 || m == 0) {
return 0;
}
int[][] dp = new int[A.length() + 1][B.length() + 1];
int maxLength = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (A.charAt(i) == B.charAt(j)) {
dp[i + 1][j + 1] = dp[i][j] + 1; // 如果相同那就在上一个字母结果上加一
if (maxLength < dp[i + 1][j + 1]) {
maxLength = dp[i + 1][j + 1];
}
}
}
}
return maxLength;
}
} dp[i][j]表示以A[i],B[j]结尾的字符串,的是最大公共子串
public int findLongest(String A, int n, String B, int m) {
int max=0;
int[][] dp=new int[n][m];
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
if(A.charAt(i)==B.charAt(j)) {
dp[i][j]=(i>=1&&j>=1)?dp[i-1][j-1]+1:1;
if(max<dp[i][j])max=dp[i][j];
}else {
dp[i][j]=0;
}
}
}
return max;
}
import java.util.*;
public class LongestSubstring {
public int findLongest(String A, int n, String B, int m) {
// write code here
int maxLen = 0;
int[] line = new int[m + 1];
// int pos = 0;
for (int i = 0; i < n; i++) {
for (int j = m; j > 0; j--) {
if (A.charAt(i) == B.charAt(j - 1)) {
line[j] = line[j - 1] + 1;
if (line[j] > maxLen) {
maxLen = line[j];
// pos = j - 1;
}
} else {
line[j] = 0;
}
}
}
// System.out.println(B.substring(pos - maxLen + 1, pos + 1));
return maxLen;
}
}
和大家思路一样,矩阵斜对角线,只不过用一行去代表整个矩阵,这一点优化。
import java.util.*;
public class LongestSubstring {
public int findLongest(String A, int n, String B, int m) {
char[] arrA = A.toCharArray();
char[] arrB = B.toCharArray();
int[][] dp = new int[n][m];
int max = 0;
for (int i = 0; i < n; i ++ )
if(arrA[i] == arrB[0]) dp[i][0] = 1;
for (int j = 0; j < m; j ++ )
if(arrB[j] == arrA[0]) dp[0][j] = 1;
for (int i = 1; i < n; i ++ ) {
for (int j = 1; j < m; j ++ ) {
if(arrA[i] == arrB[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
max = Math.max(dp[i][j], max);
}
}
}
return max;
}
}
import java.util.*;
public class LongestSubstring {
public int findLongest(String A, int n, String B, int m) {
// write code here
int p = 0,max1 = 0,count = 0,max = 0;
for(int d = 0; d < n; d++){
for(int i = 0; i < m; i++){
p = (d+i)%n;
if(p==0){
count = 0;
}
if(A.charAt(p)==B.charAt(i)){
count++;
max1 = Math.max(count,max1);
}else{
count = 0;
}
}
max = Math.max(max1,max);
count=0;
}
return max;
}
}
结果对了,两个for循环时间复杂度好像不满足要求
import java.util.*;
public class LongestSubstring {
public int findLongest(String A, int n, String B, int m) {
// write code here
int max=0;
for(int i=0;i<m;i++)
{
int temp=0;
for(int j=i+1;j<m+1;j++)
{
String subStr=B.substring(i,j);
if(A.contains(subStr))
{
temp=j-i;
}
else{
break;
}
}
if(max<temp)
{
max=temp;
}
}
return max;
}
}
class LongestSubstring { public: int findLongest(string A, int n, string B, int m) { //f[i][j] represent the longest common substring starting with A[i] and B[j] vector<vector<int>> f(n+1, vector<int>(m+1, 0)); //maxlen is the overall max common substring length, starting anywhere int maxlen = 0; //dp for(int i = n-1; i > -1; --i){ for(int j = m-1; j > -1; --j){ if(A[i] != B[j]){ //no such common substring started with A[i] and B[j] //f[i][j] remain 0 as initialized } else{ //common substring starts with A[i] and B[j] f[i][j] = f[i+1][j+1] + 1; maxlen = max(maxlen, f[i][j]); } } } return maxlen; } };