题目:给定两个字符串 strl1,strl2, 返回两个字符串的最长公共子串的长度
例如: strl1 = "1AB234" strl2 = "1234" 返回3
(牛客 HJ75公共子串计算)
这道题于左神书上的题, 有点不同(其实就是更简单了一点点),优化思路还是,参考的左神
题解:
1.硬解, 这里不做过多的描述
2.动态规划
3.更简单的升级一下2
那我们先看2.动态规划
首先,我们先看一个表格(二维数组)
我们先理解,这个表格(二维数组)干了什么?
--它用来比较字符 是否相同.
--在相同的时候, 去寻找它的前一个字符是否相同,或者说,直接在前一个字符比较的结果上+1 (不相同依旧是二维数组在i,j位置的 初始值0)
--反馈到代码就是:
if(strl1.charAt(i-1) == strl2.charAt(j-1)){num[i][j] = num[i-1][j-1]+1; }
好, 那我们现在理解, 为什么要有这个表格(二维数组)?
--首先, 这道题, 目的: 最长的公共子串字符串长度,
所以, 我们可以 拆分成小问题, 将两个字符串, 拆分成单个字符, 去比较, 字符相等, 则在前一个匹配的结果上+1 ,(前一个字符 我们已经匹配完了, 按顺序从前往后匹配的)
--于是我们知道了这是动态规划, 利用子问题的结果完成下一个步骤.
那我们现在开始写代码:
--首先创建二维数组,长度strl1,strl2
--两层for循环,比较下标位置,字符是否相等,相等则为[i-1][j-1]+1
现在,出现了问题
如果看我的图,第一行或者第一列,能匹配上,依旧[i-1][j-1]+1
是不是会出现,数组下标越界问题?
所以,我们在设定数组长度的时候要 strl1+1,strl2+1
okk,到这里大致的思路就齐全了.
你可以先自我尝试写一下代码, 如果出现了问题,可以参考一下我的代码(已经跑过了)
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String strl1 = scanner.next();String strl2 = scanner.next();int max = 0;int[][] num = new int[strl1.length()+1][strl2.length()+1];for (int i = 1; i <= strl1.length(); i++) {for (int j = 1; j <= strl2.length(); j++) {if(strl1.charAt(i-1) == strl2.charAt(j-1)){num[i][j] = num[i-1][j-1]+1;}if(max
okk,现在这道题,你已经会了,但是上述方法,其实,有一些不必要的操作
所以,现在我们来看看怎么给他升级
还是这张图,
我画线来体现出,上述代码的流程:
你看,红线 就是for循环进行一个个字符的比较,
当比较到有绿色菱形的地方(字符相等),再寻找它的上一个[i-1][j-1],的位置, 也就是紫线操作
你有没有发现,
那红色的操作就是冗余的
我们直接进行紫线操作
直接去比较,那紫线那条线不就行了?
也就是,我们只要按照顺序的,字符串的前一个字符结果
如下图操作
那我们就按图写代码, 就大功告成了!!!!~~~~~
你们可以先自己尝试一下, 体验做出来的快乐, 但是我的代码还是po到下面啦, 有什么问题, 可以再跟着代码走一遍
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String s1 = scanner.nextLine();String s2 = scanner.nextLine();//也可以不转char[] a1 = s1.toCharArray();char[] a2 = s2.toCharArray();int row = 0;int col = a2.length-1;int max = 0;while (row0){col--;} else {row++;}}System.out.println(max);}
上一篇:计算机网络【HTTP协议】