Forem

Dolly Sharma
Dolly Sharma

Posted on

Longest Common Substring

πŸ”Ή Definition

πŸ‘‰ Longest substring that is:

  • Present in both strings
  • Continuous (no skipping allowed) ❗

πŸ”Ή Difference from LCS

Feature Subsequence Substring
Continuous ❌ βœ…
DP reset ❌ βœ… (important)

πŸ”₯ Core Idea

If characters match:

dp[i][j] = 1 + dp[i-1][j-1]
Enter fullscreen mode Exit fullscreen mode

If NOT match:

dp[i][j] = 0   // πŸ”₯ RESET (this is key difference)
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Code (Correct & Clean C++)

int longestCommonSubstring(string s1, string s2) {
    int n = s1.size(), m = s2.size();

    vector<vector<int>> dp(n+1, vector<int>(m+1, 0));

    int ans = 0;

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s1[i-1] == s2[j-1]){
                dp[i][j] = 1 + dp[i-1][j-1];
                ans = max(ans, dp[i][j]);
            }
            else{
                dp[i][j] = 0;  // πŸ”₯ important
            }
        }
    }

    return ans;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Optimized Space (O(m)) πŸš€

int longestCommonSubstring(string s1, string s2) {
    int n = s1.size(), m = s2.size();

    vector<int> prev(m+1, 0), curr(m+1, 0);
    int ans = 0;

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s1[i-1] == s2[j-1]){
                curr[j] = 1 + prev[j-1];
                ans = max(ans, curr[j]);
            }
            else{
                curr[j] = 0; // reset
            }
        }
        prev = curr;
    }

    return ans;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Print Longest Common Substring

πŸ‘‰ Trick:

  • Track ending index
  • Extract substring

πŸ”Ή Code (Print substring)

string printLCSubstring(string s1, string s2) {
    int n = s1.size(), m = s2.size();

    vector<vector<int>> dp(n+1, vector<int>(m+1, 0));

    int maxLen = 0;
    int endIndex = 0;

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s1[i-1] == s2[j-1]){
                dp[i][j] = 1 + dp[i-1][j-1];

                if(dp[i][j] > maxLen){
                    maxLen = dp[i][j];
                    endIndex = i; // track end
                }
            }
        }
    }

    return s1.substr(endIndex - maxLen, maxLen);
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Example

s1 = "abcde"
s2 = "abfce"
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ Output:

"ab"
Enter fullscreen mode Exit fullscreen mode

🧠 Key Intuition

Match β†’ extend substring
Not match β†’ break (reset to 0)


⚠️ Common Mistake

❌ Writing:

dp[i][j] = max(...)
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ That is LCS (wrong problem)


πŸ”₯ Interview Tip

If interviewer says:

β€œLongest common substring”

πŸ‘‰ Immediately think:

β€œReset DP to 0 when mismatch”


πŸš€ Summary

  • Substring = continuous β†’ reset DP
  • Use diagonal only
  • Track max length

If you want next level:
βœ… Difference table (LCS vs substring vs subsequence problems)
βœ… Hard problems based on this
βœ… Visual DP table like your image

Just tell me πŸ‘

Top comments (0)