当前位置:网站首页>【牛客刷题18】 查找两个字符串a,b中的最长公共子串
【牛客刷题18】 查找两个字符串a,b中的最长公共子串
2022-04-21 06:39:00 【十叶知秋】
一、题目
题目链接:查找两个字符串a,b中的最长公共子串
二、 题目分析
两种思路,第一种常规思路,第二种动态规划。
1.常规思路一
通过遍历两个字符串str1与str2,同时维护左右两个指针,判断出重复最长的字符串即可。
- 遍历较短字符串的每个字符作为起点,不断进行子串的匹配
- 维护 左指针j,右指针k, 右指针逐渐向左逼近
- 满足子串匹配的同时还要满足子串长度是最大的
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
String str2 = sc.nextLine();
//判断两个字符串谁长谁短
if (str1.length() <= str2.length()) {
longString(str1, str2);
} else {
longString(str2, str1);
}
}
public static void longString(String str1,String str2){
//定义最大长度maxLen ,开始下标start
int maxLen = 0;
int start = 0;
for(int i = 0;i<str1.length();i++){
if(str1.length()-i-1 <= maxLen){
break;
}
for(int j =i,k=str1.length(); k>j ;k--){
String subStr = str1.substring(i,k);
if(str2.contains(subStr) && maxLen<subStr.length()){
maxLen = subStr.length();
start = j;
break;
}
}
}
System.out.println(str1.substring(start,start+maxLen));
}
}
2.常规思路2
利用StringBuilder ,把短了的字符串str1放到StringBuilder 中,然后遍历长的字符str2,判断str2当中有无StringBuilder的字符,若有,将StringBuilder的字符更新到result,直到找到最长的公共字符串。实际与常规思路1类似。
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
String str2 = sc.nextLine();
//判断两个字符串谁长谁短
if (str1.length() <= str2.length()) {
longString(str1, str2);
} else {
longString(str2, str1);
}
}
ublic static void compare(String str1, String str2) {
String result = "";
for(int i =1;i<str1.length();i++){
StringBuilder stringBuilder = new StringBuilder();
for(int j =i-1;j<str1.length();j++){
if(str2.contains(stringBuilder.append(str1.charAt(j)))){
if(stringBuilder.length() > result.length()){
result = stringBuilder.toString();
}
}
}
}
System.out.println(result);
}
}
3.动态规划思路
简单介绍一下动态规划。动态规划采用分治的思想将问题化解。把大问题化成小问题,再用小问题推导大问题的解。它有四个要素:
- 状态 ,问题中的抽象状态
- 状态转移方程
- 状态初始化
- 返回值
这道题我们需要先把状态找出来。我们的问题是:两个字符中的最长共同子串。
子问题则是:a的子串和b的子串中的最长共同子串
抽象子问题:a的前i个字符和b的前j个字符中,它们最长共同子串。
如果我们要知道最长共同子串的具体内容,则需要知道长度,起始位置,结束位置。因此我们的状态如下:
F(i,j) :以a的第i个字符结尾的子串和以b的第j个字符结尾的子串,它们的最长共同子串长度。
我们举个例子:
字符串a:abcabcde
字符串b:abcd
下面我们通过画图来阐述:

图片)
通过上面的分析,可以发现,如果a的第i个字符和b的第j个字符相同,则:
相同:F(i,j) = F(i - 1, j- 1)+1,这个实际上就是我们的转移方程。
不相同:0

那么我们的初始状态与返回值是什么?
初始状态F(0,0) = 0
返回值:最长子串的内容
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
String str2 = sc.nextLine();
//判断两个字符串谁长谁短
if (str1.length() <= str2.length()) {
longString(str1, str2);
} else {
longString(str2, str1);
}
}
public static void longString(String str1,String str2){
char[]arr1 = str1.toCharArray();
char[]arr2 = str2.toCharArray();
int len1 = arr1.length;
int len2 = arr2.length;
//定义最大长度maxLen ,开始下标start
int maxLen = 0;//最长子串的长度
int start = 0;//最长子串的起始位置
int[][] maxSubLen = new int[len1+1][len2+1];
for(int i = 1;i<=len1;i++){
for(int j =1;j<=len2;j++){
//如果第i个字符与第j个字符相等,则进行累加
if(arr1[i-1] == arr2[j-1]){
maxSubLen[i][j] = maxSubLen[i-1][j-1]+1;
//更新
if(maxLen < maxSubLen[i][j]){
maxLen = maxSubLen[i][j];
start = i - maxLen;
}
}
}
}
System.out.println(str1.substring(start,start+maxLen));
}
}
三、最后
学习最怕的就是没有收获,其实有时候想想会很奇怪,如果我们不学本就没有收获,如果我们学了,可能会有收获,那为何我们会执着于有没有收获这件事本身呢?可能是沉没成本啊,因为我本可以选择做其他事情的。那你为何不去做呢?我不知道…一顿的跟自己较劲,左右互博,又能得出什么所以然呢?题该在哪,还是在那。不来不去,动的是我们自己本身。
版权声明
本文为[十叶知秋]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_46913665/article/details/124272455
边栏推荐
- JSON encoding and decoding
- 論文閱讀:Measuring the Impact of a Successful DDoS Attack on the Customer Behaviour of Managed DNS Servi
- php Rsa加密
- fiddler调换字体后界面缺少 恢复
- Studio3t 过期激活办法/以及重新设置使用日期的脚本不可用解决办法/Studio 3T无限激活原创
- 汇编语言——内存定位的方法
- Swagger的用法以及常用注解解释
- Testing and Benchmarking
- C#linq的group、count、sum,记一下
- window 系统丢失北京时区解决方案
猜你喜欢
随机推荐
Leetcode 1387.将整数按权重排序(Sort Integers by The Power Value)
应用软件线程数与CPU核数之间的关系
压缩毕业时间到20岁以前,5岁上小学上5年,提高人口数量
Define a standard class
leetcode 707.设计链表
Leetcode 1557.可以到达所有点的最少点数目(Minimum Number of Vertices to Reach All Nodes)
leetcode 59. Spiral matrix II
When deploying. Net core on Linux platform to access SQL Server 2008 R2, it prompts the connection timeout exception
Navicat even Oracle reports an error [no matching authentication protocol]
db2相关操作知识点积累及WINDOWS环境DB2连接远程数据库实例
Regular Expressions
Environment Variables
Outh2的基本概念
C#linq的group、count、sum,记一下
每隔30秒对局域网电脑发送一次关机命令
项目存日志
PLSQL developer 14 installation details
关于DM达梦数据库,获取用户表信息、数据表结构、数据表创建语句、主键等信息的sql
批量压缩文件夹里的sql备份bak为rar,然后删除3天之前的rar
MYSQL中批量替换某个字段的部分数据









