0
点赞
收藏
分享

微信扫一扫

[动态规划]BM66 最长公共子串-中等

1 \leq |str_1|, |str_2| \leq 5\,0001≤∣str1∣,∣str2∣≤5000

描述

给定两个字符串str1和str2,输出两个字符串的最长公共子串题目保证str1和str2的最长公共子串存在且唯一。 

数据范围: [动态规划]BM66 最长公共子串-中等_动态规划

要求: 空间复杂度 [动态规划]BM66 最长公共子串-中等_动态规划_02,时间复杂度 [动态规划]BM66 最长公共子串-中等_动态规划_02

示例1

输入:

"1AB2345CD","12345EF"

返回值:

"2345"

备注:

1 1≤∣str1∣,∣str2∣≤5000

题解

思路:

  • 1. 我们可以用[动态规划]BM66 最长公共子串-中等_动态规划_04表示在str1中以第[动态规划]BM66 最长公共子串-中等_最长公共子串_05个字符结尾在str2中以第[动态规划]BM66 最长公共子串-中等_动态规划_06个字符结尾时的公共子串长度
  • 2. 遍历两个字符串填充dp数组,转移方程为:如果遍历到的该位两个字符相等,则此时长度等于两个前一位长度+1,dp[i][j]=dp[i−1][j−1]+1dp[i][j] = dp[i - 1][j - 1] + 1dp[i][j]=dp[i−1][j−1]+1,如果遍历到该位时两个字符不相等,则置为0,因为这是子串,必须连续相等,断开要重新开始。
  • 3. 每次更新[动态规划]BM66 最长公共子串-中等_动态规划_04后,我们维护最大值,并更新该子串结束位置
  • 4. 最后根据最大值结束位置即可截取出子串

代码如下:

#include <bits/stdc++.h>

using namespace std;

string LCS(string str1, string str2)
{
if (str1.empty() || str2.empty())
{
return "";
}
int end_pos = 0;// 最大长度结束标志位
int max_len = 0;// 最大长度,和 end_pos 一起用来返回最终的结果
std::vector<std::vector<int>> dp(str1.size() + 1, std::vector<int>(str2.size() + 1, 0));
for (int i = 1; i <= str1.size(); i++)
{
for (int k = 1; k <= str2.size(); ++k)
{
if (str1[i - 1] == str2[k - 1])
{
dp[i][k] = dp[i - 1][k - 1] + 1;
if (max_len < dp[i][k])
{
end_pos = i;
max_len = dp[i][k];
}
}
else
{
dp[i][k] = 0;
}
}
}
return str1.substr(end_pos - max_len, max_len);
}
举报

相关推荐

0 条评论