当前位置:网站首页>ACM. HJ75 公共子串计算 ●●
ACM. HJ75 公共子串计算 ●●
2022-06-24 23:40:00 【chenyfan_】
HJ75 公共子串计算 ●●
描述
给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。
注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。
数据范围:字符串长度: 1 ≤ s ≤ 150 1\le s\le 150 1≤s≤150
进阶:时间复杂度: O ( n 3 ) O(n^3) O(n3),空间复杂度: O ( n ) O(n) O(n)
输入描述:
输入两个只包含小写字母的字符串
输出描述:
输出一个整数,代表最大公共子串的长度
示例
输入:
asdfas
werasdfaswer
输出:
6
题解
本题与 LC 718. 最长重复子数组类似。
解法可见 C++ 数据结构与算法(十三)(动态规划 – 打家劫舍、股票问题、子序列问题)。
1. 动态规划
dp[i][j]表示以s1[i-1]、s2[j-1]为结尾(一定包括这两个字符)的字符串的公共子串长度(不一定是最大);- 初始化为0;
- 如果
s1[i-1] == s2[j-1],那么dp[i][j] = dp[i-1][j-1] + 1;,并比较更新最大长度;
否则,字符串结尾不相等,即公共长度为0. - 从前往后遍历。

- 时间复杂度: O ( n × m ) O(n × m) O(n×m),n 为A长度,m为B长度
- 空间复杂度: O ( n × m ) O(n × m) O(n×m)
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main(){
string s1, s2;
while(cin >> s1 >> s2){
int n = s1.length(), m = s2.length(), ans = 0;
vector<vector<int>> dp(n+1, vector<int>(m+1, 0));
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
if(s1[i-1] == s2[j-1]){
// 所选字符串结尾相等
dp[i][j] = dp[i-1][j-1] + 1; // 上一串长度 + 1
ans = max(ans, dp[i][j]);
} // s1[i-1] != s2[j-1] 即结尾不相同,长度为0
}
}
cout << ans << endl;
}
return 0;
}
- 一维滚动数组优化空间复杂度 O(n)
dp[i][j] 都是由dp[i - 1][j - 1]推出。那么压缩为一维数组,也就是dp[j]都是由dp[j - 1]推出。
也就是相当于可以把上一层dp[i - 1][j]拷贝到下一层dp[i][j]来继续用。
此时遍历B数组的时候,就要从后向前遍历,这样避免重复覆盖,且长度为 0 时要注意赋值。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main(){
string s1, s2;
while(cin >> s1 >> s2){
int n = s1.length(), m = s2.length(), ans = 0;
vector<int> dp(m+1, 0);
for(int i = 1; i <= n; ++i){
for(int j = m; j >= 1; --j){
if(s1[i-1] == s2[j-1]){
dp[j] = dp[j-1] + 1; // 相等
ans = max(ans, dp[j]);
}else{
dp[j] = 0; // 不相等
}
}
}
cout << ans << endl;
}
return 0;
}
2. 滑动窗口
通过滑动字符串来遍历所有字符串重叠的情况,然后在重叠部分找最大公共子串的长度。
如图可知,枚举 字符串 所有的重叠(对齐)方式主要分为三步(s1长度更小):
(1)s1 尾部开始与 s2 重叠,直到 s1 完全被覆盖;
(2)s1 头部与 s2 头部开始错位,直到 s1 尾部 与 s2 尾部重叠;
(3)s1 尾部超过 s2 尾部,直到不再重叠。
每次滑动操作需要更新两个字符串的重叠起始下标和结束下标。
- 时间复杂度: O ( ( N + M ) × min ( N , M ) ) O((N + M) \times \min(N, M)) O((N+M)×min(N,M))
- 空间复杂度: O ( 1 ) O(1) O(1)

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int getLen(string s1, string s2, int a1, int b1, int a2, int b2){
// 找到s1[a1, b1]和s2[a2,b2]的最大公共子串长度
int n = b1 - a1 + 1;
int pre = 0, ans = 0;
for(int i = 0; i < n; ++i){
if(s1[a1 + i] == s2[a2 + i]){
ans = max(ans, pre + 1);
++pre;
}else{
pre = 0;
}
}
return ans;
}
int main(){
string s1, s2;
// 滑动窗口
while(cin >> s1 >> s2){
if(s1.length() > s2.length()) swap(s1, s2);
int n = s1.length(), m = s2.length(), ans = 0; // s1 更短
for(int i = 1; i <= n; ++i){
// s1 尾部开始与 s2 重叠,直到 s1 完全被覆盖
int subLen = getLen(s1, s2, n-i, n-1, 0, i-1);
ans = max(ans, subLen);
}
for(int i = 1; i <= m-n; ++i){
// s1 头部与 s2 头部开始错位,直到 s1 尾部 与 s2 尾部重叠
int subLen = getLen(s1, s2, 0, n-1, i, n+i-1);
ans = max(ans, subLen);
}
for(int i = 1; i < n; ++i){
// s1 尾部超过 s2 尾部,直到不再重叠
int subLen = getLen(s1, s2, 0, n-1-i, m-2-n+i, m-1);
ans = max(ans, subLen);
}
cout << ans << endl;
}
return 0;
}
边栏推荐
- [live review] battle code pioneer phase 7: how third-party application developers contribute to open source
- LeetCode 210:课程表 II (拓扑排序)
- NPM package publishing tutorial
- 云原生数据库VS传统数据库
- 计算机三级(数据库)备考题目知识点总结
- 算力服务网络:一场多元融合的系统革命
- 把 Oracle 数据库从 Windows 系统迁移到 Linux Oracle Rac 集群环境(4)—— 修改 oracle11g rac 集群的 scanIP
- Centos7.3 modifying MySQL default password_ Explain centos7 modifying the password of the specified user in MySQL
- [STL source code analysis] configurator (to be supplemented)
- E - Average and Median(二分)
猜你喜欢

Once beego failed to find bee after passing the go get command Exe's pit

Lihongyi, machine learning 6 Convolutional neural network

jwt

QT package the EXE file to solve the problem that "the program input point \u zdapvj cannot be located in the dynamic link library qt5cored.dll"

Can automate - 10k, can automate - 20K, do you understand automated testing?

qt打包exe文件,解决“无法定位程序输入点_ZdaPvj于动态链接库Qt5Cored.dll”
![Network planning | [four network layers] knowledge points and examples](/img/c3/d7f382409e99eeee4dcf4f50f1a259.png)
Network planning | [four network layers] knowledge points and examples

自动化测试

分布式事务解决方案和代码落地

数据库系统概论必背知识
随机推荐
Rod and Schwartz cooperated with ZhongGuanCun pan Lianyuan Institute to carry out 6G technology research and early verification
Practice and Thinking on process memory
File system - basic knowledge of disk and detailed introduction to FAT32 file system
【STL源码剖析】配置器(待补充)
记一次beego通过go get命令后找不到bee.exe的坑
Migrate Oracle database from windows system to Linux Oracle RAC cluster environment (4) -- modify the scanip of Oracle11g RAC cluster
NPM package publishing tutorial
把 Oracle 数据库从 Windows 系统迁移到 Linux Oracle Rac 集群环境(2)——将数据库转换为集群模式
Unity archive system - file in JSON format
Kaggle 专利匹配比赛金牌方案赛后总结
DDD concept is complex and difficult to understand. How to design code implementation model in practice?
Random list random generation of non repeating numbers
Call system function security scheme
14 bs对象.节点名称.name attrs string 获取节点名称 属性 内容
3年测试经验,连简历上真正需要什么都没搞明白,张口就要20k?
Mall project pc--- product details page
【FPGA】串口以命令控制温度采集
一线城市软件测试工资——你拖后腿了吗
It's 2022, and you still don't know what performance testing is?
商城项目 pc----商品详情页