这个题是美团的2013年的研发笔试卷中的一道算法题,原题如下:
编写函数,获取两段字符串的最长公共子串的长度,例如:
S1= GCCCTAGCCAGDE
S2= GCGCCAGTGDE
这两个序列的最长公共子串是GCCAG,也就是说返回值。
1)请先描述思路;
2)编写完整代码实现,编程语言不限。
这道题跟阿里的一道笔试题如出一辙,阿里的笔试题原题如下:
题目描述:给定一个query和一个text,均由小写字母组成。要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度。例如,query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果应该为其长度3。请注意程序效率。
思路:用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.
当字符匹配的时候,不是简单的给相应元素赋上1,而是赋上其左上角元素的值加1。我们用两个标记变量来标记矩阵中值最大的元素的位置,在矩阵生成的过程中来判断当前生成的元素的值是不是最大的,据此来改变标记变量的值,那么到矩阵完成的时候,最长匹配子串的位置和长度就已经出来了。
实例如下:
a c b a c
a 1 0 0 1 0
c 0 2 0 0 2
a 1 0 0 1 0
c 0 2 0 0 2
c 0 1 0 0 1
b 0 0 2 0 0
a 1 0 0 3 0
b 0 0 1 0 0
b 0 0 1 0 0
有了上面的思路,很容易的写出如下的代码:
int longestCommonString(string s1, string s2)
{
int len = 0;
int *temp = new int[s2.length()];
memset(temp, 0, s2.length() * sizeof(int));
for (int i = 0; i < s1.length(); i++)
{
for (int j = s2.length() -1; j >= 0; j--)
{
if (s1[i] == s2[j])
{
if (i == 0 || j == 0)
temp[j] = 1;
else
temp[j] = temp[j - 1] + 1;
}
else
temp[j] = 0;
if (len < temp[j])
len = temp[j];
}
}
return len;
}