Bird
Raised Fist0
Interview Prepdp-lcs-stringmediumAmazonGoogle

Longest Common Substring

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize DP array and max_len

Create a DP array of length m+1 (6) initialized with zeros and set max_len to 0 before starting iterations.

💡 Initialization ensures we start with no common substrings counted and a clean DP array to build upon.
Line:dp = [0] * (m + 1) max_len = 0
💡 DP array length matches s2 length plus one for base case; max_len tracks longest substring found so far.
📊
Longest Common Substring - Watch the Algorithm Execute, Step by Step
Watching each update to the DP array and the max length variable reveals how the algorithm efficiently finds the longest common substring without storing the entire 2D table.
Step 1/20
·Active fill★Answer cell
Initializing dp array
i\w012345
i=0000000
initialized to 0
Item 0 - wt:0 val:0
i\w012345
i=0000000
Item 0 - wt:0 val:0
i\w012345
i=0000000
'a' != 'e', dp[5]=0
Item 0 - wt:0 val:0
i\w012345
i=0000000
'a' != 'c', dp[4]=0
Item 0 - wt:0 val:0
i\w012345
i=0000000
'a' != 'f', dp[3]=0
Item 0 - wt:0 val:0
i\w012345
i=0000000
'a' != 'b', dp[2]=0
Item 0 - wt:0 val:1
i\w012345
i=0010000
'a' == 'a', dp[1]=1
Item 1 - wt:0 val:0
i\w012345
i=0010000
Item 1 - wt:0 val:0
i\w012345
i=0010000
'b' != 'e', dp[5]=0
Item 1 - wt:0 val:0
i\w012345
i=0010000
'b' != 'c', dp[4]=0
Item 1 - wt:0 val:0
i\w012345
i=0010000
'b' != 'f', dp[3]=0
Item 1 - wt:0 val:2
i\w012345
i=0002000
'b' == 'b', dp[2]=2
Item 1 - wt:0 val:0
i\w012345
i=0002000
'b' != 'a', dp[1]=0
Item 2 - wt:0 val:0
i\w012345
i=0002000
Item 2 - wt:0 val:0
i\w012345
i=0002000
'c' != 'e', dp[5]=0
Item 2 - wt:0 val:1
i\w012345
i=0002010
'c' == 'c', dp[4]=1
Item 2 - wt:0 val:0
i\w012345
i=0002010
'c' != 'f', dp[3]=0
Item 2 - wt:0 val:0
i\w012345
i=0000010
'c' != 'b', dp[2]=0
Item 2 - wt:0 val:0
i\w012345
i=0000010
'c' != 'a', dp[1]=0
Initializing dp array
i\w012345
i=0002000
max_len = 2 (answer)

Key Takeaways

✓ The DP array stores lengths of longest common substrings ending at each position in s2 for the current character in s1.

This insight is hard to see from code alone because the 1D array updates backwards and depends on previous iteration values.

✓ Updating the DP array backwards preserves dependencies, allowing space optimization from 2D to 1D without losing correctness.

Visualizing the backward update clarifies why the algorithm avoids overwriting needed values.

✓ The max_len variable dynamically tracks the longest substring length found so far, updated only on matches.

Seeing max_len update alongside dp array changes concretely shows how the answer emerges during iteration.

Practice

(1/5)
1. Consider the following Python code implementing space-optimized DP for regex matching. What is the final return value when calling isMatch('aab', 'c*a*b')?
def isMatch(s: str, p: str) -> bool:
    m, n = len(s), len(p)
    dp = [False] * (n + 1)
    dp[0] = True
    for j in range(2, n + 1):
        if p[j - 1] == '*':
            dp[j] = dp[j - 2]
    for i in range(1, m + 1):
        prev = dp[0]
        dp[0] = False
        for j in range(1, n + 1):
            temp = dp[j]
            if p[j - 1] == '*':
                dp[j] = dp[j] or dp[j - 2]
                if p[j - 2] == '.' or p[j - 2] == s[i - 1]:
                    dp[j] = dp[j] or prev
            else:
                dp[j] = prev and (p[j - 1] == '.' or p[j - 1] == s[i - 1])
            prev = temp
    return dp[n]

print(isMatch('aab', 'c*a*b'))
easy
A. None
B. False
C. Raises IndexError
D. True

Solution

  1. Step 1: Trace dp initialization for pattern 'c*a*b'

    dp[0] = True; dp[2] = dp[0] because p[1] = '*', dp[4] = dp[2] because p[3] = '*'
  2. Step 2: Iterate over string 'aab' updating dp

    After processing all characters, dp[n] = dp[6] becomes True because 'c*' matches empty, 'a*' matches 'aa', and 'b' matches 'b'.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Known test case returns True [OK]
Hint: Pattern with '*' can match empty or multiple chars [OK]
Common Mistakes:
  • Confusing dp indices or forgetting dp initialization for '*'
2. You are given two strings and need to find the shortest string that contains both as subsequences. Which algorithmic approach guarantees finding this shortest common supersequence efficiently?
easy
A. Greedy approach that merges characters from both strings whenever they differ
B. Dynamic programming based on longest common subsequence to build the shortest supersequence
C. Pure brute force recursion enumerating all supersequences and selecting the shortest
D. Sorting characters of both strings and merging them in lexicographical order

Solution

  1. Step 1: Understand the problem requires minimal length supersequence containing both strings as subsequences

    Greedy or sorting approaches fail because they do not consider subsequence order constraints.
  2. Step 2: Recognize that longest common subsequence (LCS) helps identify overlapping parts to minimize duplication

    Dynamic programming using LCS length allows building the shortest common supersequence efficiently.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    LCS-based DP is the classic and optimal approach for shortest common supersequence [OK]
Hint: Shortest common supersequence uses LCS-based DP [OK]
Common Mistakes:
  • Thinking greedy merging always works
  • Confusing substring with subsequence
  • Assuming sorting helps
3. You need to determine if a given input string matches a pattern that may include '?' which matches any single character, and '*' which matches any sequence of characters (including empty). Which algorithmic approach guarantees an optimal solution for this problem?
easy
A. Dynamic Programming that builds a 2D table tracking matches between substrings of input and pattern
B. Pure brute force recursion trying all possible matches without memoization
C. Greedy matching by scanning both strings once, skipping characters when '*' is encountered
D. Sorting both strings and then comparing characters in order

Solution

  1. Step 1: Understand problem constraints

    The pattern includes wildcards '?' and '*', which require checking multiple matching possibilities.
  2. Step 2: Identify suitable algorithm

    Greedy or sorting approaches fail because '*' can match variable-length substrings; brute force is correct but inefficient. DP efficiently explores all subproblems with memoization.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    DP handles overlapping subproblems and wildcard flexibility [OK]
Hint: Wildcard matching requires DP, not greedy or sorting [OK]
Common Mistakes:
  • Assuming greedy works for '*' wildcard
  • Confusing brute force with DP
  • Thinking sorting helps string matching with wildcards
4. The following code attempts to find the longest palindromic substring using DP. Identify the line containing the subtle bug that causes incorrect results for some inputs.
medium
A. Line: if length < 3:
B. Line: dp[i][i] = True
C. Line: dp[i][j] = dp[i + 1][j - 1]
D. Line: for i in range(n - length + 1):

Solution

  1. Step 1: Compare condition with correct code

    The correct condition is length <= 3, but here it is length < 3, so length=3 substrings are not handled correctly.
  2. Step 2: Understand impact

    For length=3, dp[i][j] should be True if s[i]==s[j], but this code skips that, causing missed palindromes of length 3.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Changing < to <= fixes the bug [OK]
Hint: Check boundary conditions for length 3 palindromes [OK]
Common Mistakes:
  • Off-by-one in length condition
  • Confusing substring indices
  • Incorrect DP table initialization
5. What is the time and space complexity of the space-optimized bottom-up DP solution for the Minimum ASCII Delete Sum problem, given strings of lengths m and n?
medium
A. Time: O(m+n), Space: O(m+n)
B. Time: O(m*n), Space: O(n)
C. Time: O(m*n), Space: O(m*n)
D. Time: O(2^(m+n)), Space: O(m+n)

Solution

  1. Step 1: Identify nested loops

    Outer loop runs m times, inner loop runs n times -> total O(m*n) time.
  2. Step 2: Analyze space usage

    Only one dp array of size n+1 is used, so space is O(n).
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Matches known DP optimization for string problems [OK]
Hint: Nested loops multiply time; dp array size defines space [OK]
Common Mistakes:
  • Confusing recursion stack space with DP array space
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard