DSA AnimatorDSA animations
Word Break LC #139 Medium DP on Strings
Problem

Given a string s and a dictionary of strings wordDict, return true if s can be split into a sequence of one or more dictionary words. The same word may be reused any number of times.

Example 1
Input: s = "leetcode", wordDict = ["leet","code"]
Output: true ("leet code")
Example 2
Input: s = "applepenapple", wordDict = ["apple","pen"]
Output: true ("apple pen apple" — words can be reused)
Example 3
Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
Output: false
Constraints: 1 ≤ s.length ≤ 300  |  1 ≤ wordDict.length ≤ 1000  |  lowercase English letters
📖 String & dictionary
⬆ dp[i] sits on the cut after the first i letters · ✅ buildable · ❌ not buildable
dictionary lookups: 0cuts skipped (dp[j] = ❌): 0
Variables
i (prefix length)
—
j (cut)
—
s[j..i)
—
dp[i]
—
💡 Step Logic
Press ▶ Play or Next to begin.
✓
Ready
0 / 0
Pick an example and press Play.
Algorithm
1
Put the words in a HashSet; set dp[0] = true (empty prefix)
2
For each prefix length i = 1..n, try every earlier cut j
3
If dp[j] is ✅ and s[j..i) is a word → dp[i] = true, stop trying cuts
4
Return dp[n]
Time
O(n² · m)
Space
O(n)
🧠 Why DP, not greedy?

Greedy "always take the longest word" fails: for "abcd" with ["a","abc","b","cd"], grabbing "abc" leaves "d", which is no word, yet "a | b | cd" works. DP remembers every reachable cut, so no choice is ever lost. Speed-up: only try cuts j ≥ i − longestWord, since a longer piece can't be a word. (m = cost of building each substring.)

⚠️ Edge cases

Reusing words is allowed ("apple pen apple"). Almost-fits strings like "catsandog" fail only at the very end. That's why you must check dp[n], not just "most letters covered". A single-word string is true if that word is in the dictionary.

How to solve Word Break

LeetCode 139 · Medium · Dynamic Programming · Pattern: 1D DP over Prefixes

Why the obvious approach is slow

Trying every split recursively repeats the same suffix checks many times. Remember which prefixes can be built.

The key idea

Let dp of i be true when the first i characters can be split into words. The empty prefix is always fine, so dp of 0 is true. For each end position i, look for a split point j where dp of j is true and the part from j to i is a dictionary word. If such a j exists, dp of i is true. The answer is dp of n.

Remember

Dp over prefixes, with a split point j. A true dp of j plus a dictionary word extends the prefix.

Run the animation above on your own input, or watch the 1:50 video explanation of Word Break with a dry run and Java code.

More Dynamic Programming problems