Word Break medium
Description
Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words.
You may reuse dictionary words.
Examples
> Case 1:
s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: "leet code".
> Case 2:
s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
> Case 3:
s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: falseConstraints
1 <= s.length <= 3001 <= wordDict.length <= 10001 <= wordDict[i].length <= 20
State design
Think of it as unbounded knapsack on a string: “coins” = words, “amount” = prefix length. Can we tile a prefix of length i using dictionary words?
- What am I computing?
dp[i]= can the prefixs[0..i)be segmented? - Dimensions? One — prefix length
i. - Base cases?
dp[0] = true(empty string trivially segments). - Transition?
dp[i]istrueiff there’s some split pointj < iwheredp[j] == trueands[j..i)is in the dictionary. - Order? Increasing
ifrom 1 ton. - Answer?
dp[n].
For a fast dictionary lookup, store wordDict in a hash set.
Code
A practical speedup
The inner loop tries every prior split point. But the only useful split points are those at j = i - len(word) for some word in the dictionary. If you know the max word length L, you can restrict the inner loop to the last L positions:
max_len = max((len(w) for w in word_dict), default=0)
for i in range(1, n + 1):
for j in range(max(0, i - max_len), i):
if dp[j] and s[j:i] in words:
dp[i] = True
breakFor dictionaries with short words and long input strings, this is a big constant-factor win.
For an even faster approach, build a Trie of dictionary words and at each i walk the trie character-by-character from s[i] forward — every “word ends here” node marks a legal split. Same overall O(n × max_len) time but no string-hashing overhead. (We cover Tries on Day 18.)
Analysis
- Time:
O(n²)plus the cost of substring hashing. With max-word-length truncation,O(n × L)whereLis the longest word. - Space:
O(n)for the DP table, plus the dictionary.
Same skin
- Word Break II — return all segmentations. Same DP for feasibility; reconstruct sentences via backtracking using the DP table as a pruning oracle.
- Concatenated Words — for each word in the input list, run Word Break with the dictionary being all other words.
- Sentence Screen Fitting — different problem, similar word-by-word DP shape.