Lesson 55 — DP IX: Segmentable Prefixes

~25 minutes · Day 72 · dynamic programming

Tonight's interview shape is Word Break: given a string and a dictionary of words, decide whether the string can be split into valid dictionary chunks. The hard part is not checking one split. The hard part is avoiding the same suffix question over and over.

The invariant

dp[i] answers “can the first i characters be segmented?” — true iff some earlier true dp[j] is followed by a dictionary word spanning j to i.

That sentence is the whole pattern. A true cell means a prefix is usable ground. From that ground, one dictionary word can carry you to a later true cell.

Word Break: the slow way first

The brute force is to try every possible sequence of cuts: first word here, next word there, then recurse on the remaining suffix. That is exponential, O(2^n), because the same starting positions get retried through many different cut paths.

Dynamic programming keeps only the useful yes/no answer for each prefix. Use the four DP questions from the training plan:

Python's set removes duplicate dictionary words, and str.startswith can test whether a word starts at a chosen index.

def wordBreak(s, wordDict):
    words = set(wordDict)                 # unique dictionary words
    n = len(s)
    dp = [False] * (n + 1)
    dp[0] = True                          # empty prefix works
    for j in range(n + 1):
        if not dp[j]:
            continue                      # cannot extend a false prefix
        for word in words:
            i = j + len(word)
            if i <= n and s.startswith(word, j):
                dp[i] = True              # word spans j -> i
    return dp[n]

The state space

Word Break DP transition from one true prefix to another A row of DP cells for leetcode. The cell at index 4 is true, and an arrow labeled with the transition word code points to index 8, making dp 8 true. Example: s = “leetcode”, dictionary = {“leet”, “code”} dp[0] true dp[1] false dp[2] false dp[3] false dp[4] true dp[5] false dp[6] false dp[7] false dp[8] true transition: dp[0] true + “leet” -> dp[4] true transition: dp[4] true + “code” -> dp[8] true
The arrow is the recurrence: a true prefix plus one dictionary word creates a later true prefix.

Transfer: same question, new costume

A product code is valid if it can be assembled from approved chunks. Given s = "applepenapple" and chunks ["apple", "pen"], predict the state, transition, base case, and answer location before opening the reveal.

Your prediction first — then reveal.

Use the same prefix table. dp[0] starts true. From dp[0], the word "apple" spans to dp[5]. From dp[5], "pen" spans to dp[8]. From dp[8], "apple" spans to dp[13]. The answer is dp[13] = True.

What the trade buys you

ApproachTimeSpace
Brute force (try every cut path)O(2^n)O(n)
DP prefix table (extend true prefixes)O(n * W * L)O(n + W)

Here n is the string length, W is the number of dictionary words, and L is the longest word length. The memory buys you a promise: each prefix question is stored once.

Practice — answer before you scroll past

1. What does dp[i] mean?

2. When can dp[i] become true?

3. Spot the bug in this setup:

dp = [False] * (len(s) + 1)
for j in range(len(s) + 1):
    if dp[j]:
        # try words from j

4. Which prompt is this pattern in disguise?

Your move (tonight)

Solve this on LeetCode, logging it in your Notion tracker with the cycle — predict → attempt → compare → encode:

  1. Word Break — predict the prefix state, attempt the DP table, compare only after your attempt, then encode the invariant in your own words.

For the encode step, write four short sentences: state, transition, base case, answer location. That is the DP self-check gate for this lesson.

One primary source

Watch NeetCode — Word Break after your attempt, as the compare step. Find the exact sentence where his reasoning diverges from yours.