题目描述:
给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1
输入描述:
输入包含两行,第一行代表字符串str1,第二行代表字符串str2。(1<=length(str1),length(str2)<=5000)
输出描述:
输出包含一行,代表最长公共子串
示例1:
输入描述:
1AB2345CD
12345EF
输出描述:
2345
备注:
时间复杂度O(n2),额外空间复杂度O(1)。
方法2:遍历斜线法
解题思路:参考DP方法,dp[i][j]的状态只取决于dp[i-1][j-1],在dp矩阵上观察到,只需要统计从左向右、从上至下的最长子字符串,不需要在使用m*n大小的辅助空间,只需要记录斜线上最长子字符串的长度
实现方法:
从右上角开始遍历,对于每一条斜线(row, col变量确定斜线起始位置),从第0行开始(i=0),维护一个变量tmp记录出现的最长子字符串长度,如果str1[i] == str2[j],tmp++,同时更新maxLength,如果str1[i] != str2[j],tmp清零
代码如下:
#include<iostream>
#include<vector>
using namespace std;
string longestSubString(string s1, string s2) {
int n = s1.size();
int m = s2.size();
int maxLength = 0;
int row = 0, col = m - 1;
int l, r;
int tmp;
while (row < n) {
tmp = 0;
int i = row, j = col;
while (i < n && j < m) {
if (s1[i] == s2[j]) {
tmp++;
if (tmp > maxLength) {
maxLength = tmp;
l = i - tmp + 1, r = i;
}
}else {
tmp = 0;
}
i++, j++;
}
if (col == 0) row++;
else col--;
}
res = s1.substr(l, maxLength);
return res;
}