Arian Soleimanzadeh
  • 首页
  • 博客
  • 播客
  • 视频
  • 联系
العربيةArabic
DeutschGerman
EnglishEnglish
فارسیPersian
한국어Korean
中文Chinese
面板•快速联系

Languages

Choose your interface locale

ar

العربية

Arabic

de

Deutsch

German

en

English

English

fa

فارسی

Persian

ko

한국어

Korean

zh

中文

Chinese

预约咨询

发送一条简短消息——我会尽快回复。

LinkedIn快速回复
首页/文章/什么是 Longest Common Substring?使用动态规划寻找最长公共子串
Algorithms文章

什么是 Longest Common Substring?使用动态规划寻找最长公共子串

Longest Common Substring 用于寻找两个字符串中最长的连续公共片段。本文介绍动态规划状态、TypeScript 实现、复杂度、空间优化以及与 LCS 的区别。

2026年8月19日7 分钟阅读0 浏览
#Algorithms#Longest Common Substring#String Algorithms#Dynamic Programming#TypeScript

Arian Soleimanzadeh

Software Engineer & Researcher

使用动态规划矩阵寻找两个字符串 Longest Common Substring 的示意图

Arian Soleimanzadeh

AI · 代码 · 产品

研究 + 工程
本页目录
Substring 必须连续动态规划定义示例 DP 表TypeScript 实现复杂度与 Longest Common Subsequence 的区别实际应用多个最优答案技术面试重点总结

Longest Common Substring 问题要求找出两个字符串中最长的连续公共字符序列。

例如:

ABABC
BABCA

最长的公共连续部分是:

BABC

因此:

Length = 4

Substring 必须连续

对于:

ABCDE

以下都是 Substring:

ABC
BCD
DE

但是 ACE 不是,因为字符并不连续。

动态规划定义

定义:

dp[i][j]

表示恰好在 a[i - 1] 和 b[j - 1] 位置结束的最长公共子串长度。

如果当前字符相同:

dp[i][j] = dp[i - 1][j - 1] + 1

如果不同:

dp[i][j] = 0

之所以重置为 0,是因为 Substring 必须连续,任何 mismatch 都会打断当前匹配链。

示例 DP 表

对于:

a = ABABC
b = BABCA

可以得到:

      B  A  B  C  A
A     0  1  0  0  1
B     1  0  2  0  0
A     0  2  0  0  1
B     1  0  3  0  0
C     0  0  0  4  0

最大值为 4,对应 BABC。

TypeScript 实现

function longestCommonSubstring(
  a: string,
  b: string
): string {
  const dp = Array.from(
    { length: a.length + 1 },
    () => new Array(b.length + 1).fill(0)
  );

  let maxLength = 0;
  let endIndex = 0;

  for (let i = 1; i <= a.length; i++) {
    for (let j = 1; j <= b.length; j++) {
      if (a[i - 1] === b[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;

        if (dp[i][j] > maxLength) {
          maxLength = dp[i][j];
          endIndex = i;
        }
      }
    }
  }

  return a.slice(endIndex - maxLength, endIndex);
}

复杂度

如果两个字符串长度分别是 n 和 m:

Time Complexity: O(n × m)
Space Complexity: O(n × m)

由于当前行只依赖上一行,可以把空间优化到:

O(min(n, m))

与 Longest Common Subsequence 的区别

Substring 要求字符连续。

Subsequence 只要求顺序保持一致。

例如:

ABCDEF
ACEF

ACEF 可以是 Common Subsequence,但并不是第一个字符串中的连续 Substring。

动态规划中最明显的区别是:

Longest Common Substring mismatch → 0

而 LCS 在 mismatch 时通常会从相邻状态中选择较大值。

实际应用

Longest Common Substring 可用于:

  • 字符串相似度
  • CRM 数据去重
  • Data Cleaning
  • DNA Sequence 分析
  • 文档比较
  • 版本比较
  • Log Pattern 分析

例如在 CRM 数据清洗中,较长的公共字符串可以成为两个记录可能相关的一个 Signal,但生产环境还应该结合 Email、Phone、Levenshtein Distance 和 Token Similarity 等信息。

多个最优答案

可能存在多个相同最大长度的公共 Substring。

例如:

abcXYZ123
abcABC123

abc 和 123 的长度都为 3。

技术面试重点

需要理解:

  • Substring 必须连续。
  • dp[i][j] 的含义。
  • mismatch 时为什么重置为 0。
  • 为什么要单独维护最大值。
  • 时间复杂度为 O(n × m)。

总结

Longest Common Substring 的核心状态转移非常直接:

Match    → dp[i - 1][j - 1] + 1
Mismatch → 0

这也是它与 Longest Common Subsequence 最重要的区别。

本页目录
Substring 必须连续动态规划定义示例 DP 表TypeScript 实现复杂度与 Longest Common Subsequence 的区别实际应用多个最优答案技术面试重点总结

文章信息

发布时间、阅读时长和浏览数据。

发布

2026年8月19日

更新

2026年8月19日

阅读时长

7 分钟阅读

浏览

0

作者

Arian Soleimanzadeh

下一篇

什么是 Palindrome?使用双指针和 TypeScript 判断回文

让我们构建清晰、快速而优雅的作品。

用于合作、咨询或产品工作的快速联系入口。

快速联系给我发邮件
Arian Soleimanzadeh

个人作品集,聚焦现代 Web 工程、UI 系统与实用型 AI 产品——干净的代码,清晰的设计。

快速链接

  • 关于
  • 博客
  • 项目
  • 联系

联系

  • info@ariansoleimanzadeh.site
  • soleimanzadeh.a.work@gmail.com

可联系时间: 工作日

通常回复时间在 24小时内。

订阅通讯

获取文章、项目与新版本发布的更新。

© 2026 ariansoleimanzadeh.site — 保留所有权利。

LinkedIn