dp[i][j] хранит длину общего суффикса для префиксов a[0..i) и b[0..j). При совпадении символов: dp[i-1][j-1]+1, иначе 0. Отслеживаем максимум и конец.Время – O(n·m), память – O(n·m).
1/**2 * Самая длинная общая подстрока (Longest Common Substring).3 */4function longestCommonSubstring(a: string, b: string): { length: number; substring: string } {5 const n = a.length, m = b.length;6 const dp: number[][] = Array.from({ length: n + 1 }, () => Array(m + 1).fill(0));7 let maxLen = 0, endA = 0;8 for (let i = 1; i <= n; i++) {9 for (let j = 1; j <= m; j++) {10 if (a[i - 1] === b[j - 1]) {11 dp[i][j] = dp[i - 1][j - 1] + 1;12 if (dp[i][j] > maxLen) { maxLen = dp[i][j]; endA = i; }13 } else dp[i][j] = 0;14 }15 }16 return { length: maxLen, substring: a.slice(endA - maxLen, endA) };17}1819// Примеры20longestCommonSubstring('hish', 'fish') // length -> 3, substring -> 'ish'21longestCommonSubstring('blue', 'clues') // length -> 3, substring -> 'lue'22longestCommonSubstring('ABABC', 'BABCA') // length -> 4, substring -> 'BABC'