2Brute2Best
🔥0
03

Common substring (DP — Strings Sub-pattern)

Like LCS, but the common part must be contiguous: dp[i][j] is the length of the common run ending exactly at a[i − 1] and b[j − 1].

Signals in the problem statement
  • ›

    "longest common substring"

  • ›

    "maximum length of repeated subarray"

  • ›

    "contiguous" in a two-string question

What makes it different

Mismatch → 0, not max(top, left). The answer is the largest cell, wherever it is.

Questions

ordered from “learn the idea” to “recognise it without help”
  1. 1
    Longest Common Substring
    Basic Anchor·GeeksforGeeks
    Medium
  2. 2
    Maximum Length of Repeated Subarray
    Basic Reinforcement·LeetCode #718
    Medium

Template

common-substring-template.cpp
// Longest common substring: dp[j] = length of the common run ending at a[i - 1] and b[j - 1].
// A mismatch breaks the run (0). j goes high -> low so dp[j - 1] is still the previous row.
int longestCommonSubstring(const string& a, const string& b) {
    int m = b.size(), best = 0;
    vector<int> dp(m + 1, 0);
    for (size_t i = 1; i <= a.size(); i++)
        for (int j = m; j >= 1; j--) {
            dp[j] = a[i - 1] == b[j - 1] ? dp[j - 1] + 1 : 0;
            best = max(best, dp[j]);                 // the answer can end anywhere
        }
    return best;
}
Remember this · DP — Strings
Trigger
Longest common subsequence, edit distance, palindromes, matching with wildcards, interleaving.
Think
Look at the last characters: if they match, what do I do? If not, what are my options?
Key question
What does dp[i][j] mean, and what are the empty-string base cases?