Bird
Raised Fist0
Interview Prepdp-lcs-stringhardAmazonFacebookGoogleBloomberg

Word Break II (All Sentences)

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize dp array with empty lists and base case

Create a dp array of length n+1 where each element is an empty list. Set dp[n] to contain an empty string as the base case, representing an empty suffix.

💡 This base case allows the algorithm to build sentences backward by appending words to sentences starting at the end.
Line:dp = [[] for _ in range(n + 1)] dp[n] = [""]
💡 The base case dp[n] = [''] is essential to start building sentences from the end of the string.
📊
Word Break II (All Sentences) - Watch the Algorithm Execute, Step by Step
Watching the dp array fill step-by-step reveals how the algorithm builds all valid sentences incrementally, which is hard to grasp from code alone.
Step 1/20
·Active fill★Answer cell
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
Base case dp[n] = ['']
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
Filling dp[9]
Item 4 - wt:3 val:0
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
No match for 'dog'
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
dp[9] = []
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
Filling dp[8]
Item 4 - wt:3 val:0
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
Match 'dog'
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
dp[8] = ['dog']
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
Filling dp[7]
Item 2 - wt:3 val:0
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
No match 'and'
Item 3 - wt:4 val:0
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
No match 'sand'
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
dp[7] = []
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
Filling dp[6]
Item 2 - wt:3 val:0
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8dog
i=9
i=10
No sentences from dp[9]
Item 3 - wt:4 val:0
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6sand
i=7
i=8dog
i=9
i=10
Match 'sand'
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6sand
i=7
i=8dog
i=9
i=10
dp[6] = ['sand']
Initializing dp array
i\w
i=0
i=1
i=2
i=3
i=4
i=5
i=6sand
i=7
i=8dog
i=9
i=10
Filling dp[3]
Item 2 - wt:3 val:0
i\w
i=0
i=1
i=2
i=3and sand
i=4
i=5
i=6sand
i=7
i=8dog
i=9
i=10
Match 'and'
Item 3 - wt:4 val:0
i\w
i=0
i=1
i=2
i=3and sand
i=4
i=5
i=6sand
i=7
i=8dog
i=9
i=10
No match 'sand'
Initializing dp array
i\w
i=0
i=1
i=2
i=3and sand
i=4
i=5
i=6sand
i=7
i=8dog
i=9
i=10
dp[3] = ['and sand']
Initializing dp array
i\w01
i=0cat and sandcats and dog
i=1
i=2
i=3and sand
i=4
i=5
i=6sand
i=7
i=8dog
i=9
i=10
Final dp[0]

Key Takeaways

✓ The dp array stores all possible sentences starting at each index, built from the end backward.

This insight is hard to see from code alone because the dp array holds lists of strings, not just counts or booleans.

✓ Each dp[i] depends on dp[i + len(word)] for matching dictionary words, showing a backward dependency chain.

Visualizing this dependency clarifies why the algorithm fills dp from the end to the start.

✓ When multiple dictionary words match at the same position, dp[i] accumulates sentences from all branches, enabling multiple valid segmentations.

Seeing the branching in dp[i] helps understand how all valid sentences are collected.

Practice

(1/5)
1. What is the time complexity of the space-optimized bottom-up dynamic programming solution for the edit distance problem, where m and n are the lengths of the two input strings?
medium
A. O(m + n)
B. O(m * n)
C. O(m * n * min(m, n))
D. O(m * n * log n)

Solution

  1. Step 1: Identify nested loops over both strings

    The algorithm has two nested loops: outer over m and inner over n.
  2. Step 2: Calculate total operations

    Each cell dp[j] is updated once per iteration, so total operations are proportional to m * n.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Double loop over m and n -> O(m*n) [OK]
Hint: Nested loops over both strings imply O(m*n) time [OK]
Common Mistakes:
  • Confusing with linear O(m+n)
  • Adding extra factor min(m,n) incorrectly
  • Assuming logarithmic factor
2. The following code attempts to implement the space-optimized DP for the interleaving string problem. Identify the line containing the subtle bug that can cause incorrect results.
medium
A. Line 12: inner loop iterating forward instead of backward
B. Line 10: dp[0] update before inner loop
C. Line 7: dp initialization with False values
D. Line 5: length check of s3 against s1 and s2

Solution

  1. Step 1: Understand dp update order

    The dp array must be updated from right to left (descending j) to avoid overwriting dp[j-1] before it is used.
  2. Step 2: Identify bug

    The inner loop iterates forward (j from 1 to n), which corrupts dp states and leads to incorrect results.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Backward iteration preserves previous row info; forward breaks correctness [OK]
Hint: Space-optimized DP requires backward inner loop update [OK]
Common Mistakes:
  • Updating dp forward overwrites needed states
  • Forgetting length check causes unnecessary computation
3. The following code attempts to implement the space-optimized DP for longest common substring. Identify the line containing the subtle bug that causes incorrect results on some inputs.
def longest_common_substring_space_optimized_buggy(s1, s2):
    n, m = len(s1), len(s2)
    dp = [0] * (m + 1)
    max_len = 0
    for i in range(1, n + 1):
        for j in range(1, m + 1):  # Note: iterating forward
            if s1[i - 1] == s2[j - 1]:
                dp[j] = dp[j - 1] + 1
                if dp[j] > max_len:
                    max_len = dp[j]
            else:
                dp[j] = 0
    return max_len
medium
A. Line with 'dp[j] = dp[j - 1] + 1' updating dp
B. Line with 'dp = [0] * (m + 1)' initializing dp array
C. Line with 'if dp[j] > max_len:' updating max_len
D. Line with 'for j in range(1, m + 1):' iterating forward

Solution

  1. Step 1: Understand dp array update dependency

    dp[j] depends on dp[j-1] from previous iteration of inner loop, so iterating forward overwrites dp[j-1] before use.
  2. Step 2: Identify iteration order bug

    Iterating j forward causes dp[j-1] to be updated before dp[j], corrupting the chain of matching lengths.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Changing inner loop to iterate backward fixes the bug [OK]
Hint: DP update depends on previous dp[j-1], so iterate backward [OK]
Common Mistakes:
  • Updating dp forward overwrites needed values
  • Incorrect max_len update timing
  • Wrong dp initialization size
4. Examine the following buggy code snippet for wildcard matching using space-optimized DP. Which line contains the subtle bug that causes incorrect results on empty strings or patterns?
medium
A. Line 14: curr[j] = curr[j - 1] or prev[j]
B. Line 10: curr = [False] * (n + 1) initialization
C. Line 6: prev[j] = True instead of prev[j] = prev[j - 1]
D. Line 17: curr[j] = prev[j - 1]

Solution

  1. Step 1: Analyze initialization of prev array for '*' characters

    Line 6 sets prev[j] = True unconditionally when p[j-1] == '*', which incorrectly assumes all prefixes match.
  2. Step 2: Correct initialization logic

    It should propagate previous state: prev[j] = prev[j - 1], ensuring '*' can match empty sequence only if previous prefix matched.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Incorrect initialization causes false positives on empty strings [OK]
Hint: Initialization must propagate previous True states for '*' [OK]
Common Mistakes:
  • Setting prev[j] = True blindly
  • Ignoring empty string edge cases
  • Confusing '*' handling in initialization
5. Suppose you want to count the number of distinct subsequences of t in s, but now characters in s can be reused multiple times (i.e., you can use the same character in s multiple times to form subsequences). Which modification to the DP approach correctly solves this variant?
hard
A. Use a 2D DP where dp[i][j] counts subsequences using first i chars of s and j chars of t, but allow reusing s[i] by not incrementing i on match
B. Change the recurrence to allow staying at the same i index when matching characters
C. Use the same DP but iterate j forward instead of backward in the inner loop
D. No change needed; original DP already counts subsequences with reuse

Solution

  1. Step 1: Understand reuse means characters in s can be used multiple times

    Original DP assumes each character in s can be used at most once per subsequence.
  2. Step 2: Modify DP to allow reusing s[i]

    Use 2D DP where dp[i][j] counts subsequences using first i chars of s for first j chars of t, and when s[i] matches t[j], allow staying at i (not incrementing) to reuse character.
  3. Step 3: Recognize that iterating j forward or no change won't handle reuse correctly

    Only explicit state allowing reuse by not advancing i on match works.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Allowing reuse requires 2D DP with careful state transitions [OK]
Hint: Reuse means allowing same s[i] multiple times, so must not always increment i
Common Mistakes:
  • Assuming original DP handles reuse
  • Trying to fix by changing iteration order only
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