华为机试牛客刷题之HJ75 公共子串计算

HJ75 公共子串计算

描述

对于给定的两个字符串s和t,你需要找出它们的最长公共子串的长度。

子串为从原字符串中,连续的选择一段字符(可以全选、可以不选)得到的新字符串。

如果字符串 α 的一个子串 a'与字符串b的一个子串b 完全相等,那么子串 α',b'是字符串a,b的一个公共子串。

输入描述:

第一行输入一个长度为 1 <= len(s)<= 150、仅由小写字母组成的字符串 s。

第二行输入一个长度为 1 <= len(t)<= 150、仅由小写字母组成的字符串 t。

输出描述:

输出一个整数,代表s和t的最长公共子串的长度。

示例1

复制代码
输入:
awaabb
aawbb
输出:
2
说明:在这个样例中,"aa" 和 "bb" 都是 s 和 t 的最长公共子串。

示例2

复制代码
输入:
asdfas
werasdfaswer
输出:
6

以下是把代码喂给deepseek后对 最长公共子串 代码的通俗易懂解释,结合生活中的比喻帮助理解:


1. 问题场景

假设你有两个字符串:

  • 字符串1:"abcdefg"
  • 字符串2:"zbcdf"

你想找到它们最长的 连续相同部分 (子串)。比如它们的共同子串是 "bcd",长度为 3


2. 动态规划思想

我们用一个 表格 (二维数组 dp)来记录每一步的"最长连续相同部分长度"。

表格定义
  • dp[i][j] 表示:以字符串1的第 i 个字符 和 字符串2的第 j 个字符 结尾 的最长公共子串长度。

例如:

  • dp[3][2] 表示以字符串1的第3个字符(比如 c)和字符串2的第2个字符(比如 b)结尾的最长公共子串长度。

3. 填表规则

(1) 当前字符匹配

如果字符串1的第 i 个字符和字符串2的第 j 个字符相同:

  • 相当于连续相同部分多了一个字符,所以当前长度 = 左上角的值 + 1。
  • 公式dp[i][j] = dp[i-1][j-1] + 1
    (比如之前的连续相同部分是 "bc",现在多了 d,变成 "bcd"
(2) 当前字符不匹配

如果字符不同:

  • 连续相同部分中断,当前长度重置为 0。
  • 公式dp[i][j] = 0

4. 代码逐行解释

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) { // 处理多组输入
            String text1 = in.nextLine(); // 输入字符串1
            String text2 = in.nextLine(); // 输入字符串2
            int m = text1.length(); // 字符串1的长度
            int n = text2.length(); // 字符串2的长度
            int[][] dp = new int[m + 1][n + 1]; // 创建动态规划表格
            int result = 0; // 记录最长公共子串的长度

            // 遍历字符串1的每个字符
            for (int i = 1; i <= m; i++) {
                char temp1 = text1.charAt(i - 1); // 当前字符
                // 遍历字符串2的每个字符
                for (int j = 1; j <= n; j++) {
                    char temp2 = text2.charAt(j - 1); // 当前字符
                    if (temp1 == temp2) { // 如果字符匹配
                        dp[i][j] = dp[i - 1][j - 1] + 1; // 长度 = 左上角值 + 1
                        result = Math.max(result, dp[i][j]); // 更新最大值
                    } else { // 如果字符不匹配
                        dp[i][j] = 0; // 重置为0
                    }
                }
            }
            System.out.println(result); // 输出最长公共子串的长度
        }
    }
}

5. 实际例子

假设 text1 = "abcdefg"text2 = "zbcdf",它们的 最长公共子串"bcd",长度为 3。填表过程如下:

a b c d e f g
0 0 0 0 0 0 0 0 0
z 0 0 0 0 0 0 0 0
b 0 0 1 0 0 0 0 0
c 0 0 0 2 0 0 0 0
d 0 0 0 0 3 0 0 0
f 0 0 0 0 0 0 1 0
  • 关键步骤
    • i=2(字符 b)和 j=2(字符 b)时,匹配成功,长度更新为 dp[1][1] + 1 = 0 + 1 = 1
    • i=3(字符 c)和 j=3(字符 c)时,匹配成功,长度更新为 dp[2][2] + 1 = 1 + 1 = 2
    • i=4(字符 d)和 j=4(字符 d)时,匹配成功,长度更新为 dp[3][3] + 1 = 2 + 1 = 3

6. 总结

  • 核心思想:通过表格记录以每个字符结尾的最长公共子串长度,逐步推导全局最大值。
  • 时间复杂度:O(mn),其中 m、n 是字符串长度。
  • 适用场景:文本匹配、基因序列分析等需要找连续相同部分的场景。

相关推荐
风铃儿~2 分钟前
Spring AI 入门:Java 开发者的生成式 AI 实践之路
java·人工智能·spring
斯普信专业组8 分钟前
Tomcat全方位监控实施方案指南
java·tomcat
忆雾屿18 分钟前
云原生时代 Kafka 深度实践:06原理剖析与源码解读
java·后端·云原生·kafka
武昌库里写JAVA31 分钟前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
ai产品老杨39 分钟前
减少交通拥堵、提高效率、改善交通安全的智慧交通开源了。
前端·vue.js·算法·ecmascript·音视频
gaoliheng00640 分钟前
Redis看门狗机制
java·数据库·redis
我是唐青枫42 分钟前
.NET AOT 详解
java·服务器·.net
小于不是小鱼呀43 分钟前
手撕 K-Means
人工智能·算法·机器学习
m0_740154671 小时前
K-Means颜色变卦和渐变色
算法·机器学习·kmeans
Su米苏1 小时前
Axios请求超时重发机制
java