Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns  Module 24 – Dynamic programming: foundations

Segmenting strings with a dictionary

Split a string without spaces, such as a hashtag, into dictionary words: decide whether it can be done, list every way, and see why the brute force explodes.

  • Intermediate
  • 35 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0, quickjs 0.32.0, Java 25.0.4.1, Clang 21.0.0 and Go 1.27.1
  • By MySmartCoPilot
Free intro, Pro: 9 of 35 minutes free
Free: Two problems: can a hashtag be split, and in which ways? · The brute force, and why it fails · What to notice. With a pass: the other 11 sections and 3 interview answers, about 26 minutes.

What you will learn

  • Decide whether a string splits into dictionary words with a table over cut positions
  • Limit the inner loop of the table to the length of the longest word
  • Count the segmentations modulo 10^9 + 7 and keep feasibility apart from the count
  • List every segmentation with memoised suffixes, after checking that the output is small
  • Compare a set of words with a trie that stops at the first missing prefix

Before you start

What you’ll learn · Before you start

What you will learn

  • Decide whether a string splits into dictionary words with a table over cut positions
  • Limit the inner loop of the table to the length of the longest word
  • Count the segmentations modulo 10^9 + 7 and keep feasibility apart from the count
  • List every segmentation with memoised suffixes, after checking that the output is small
  • Compare a set of words with a trie that stops at the first missing prefix

Before you start

On this page

Word segmentation splits a string written without spaces, such as a hashtag, into words from a dictionary. Two questions come with it: can the string be split at all, and in which ways? Both have a table over the cut positions between letters, where each position asks whether, or in how many ways, the rest of the string can be split. Listing every way is different, because the number of segmentations can grow exponentially with the length, so the listing must check its size before it builds anything. This lesson poses both questions on original hashtags.

Two problems: can a hashtag be split, and in which ways?

Problem A, can it be split? Given a string of lowercase letters and a dictionary, decide whether the string can be cut into dictionary words, each word usable any number of times. Limits: 1 ≤ len(text) ≤ 10,000, up to 1,000 words of 1 to 20 letters.

Problem B, every segmentation. Return every way to cut the string into words, each as words separated by spaces. The inputs are promised to have at most 10,000 segmentations.

  • monsoonsale with the words mon, monsoon, soon, so, on, sale, sal and ale can be split in 3 ways: mon so on sale, mon soon sale and monsoon sale.
  • goldencoin with gold, golden, coins and den cannot be split: coin is not a word, only coins is.
Positions 0 to 11 of the hashtag monsoonsale joined by dictionary words; three paths reach the end, and position 10 is a dead end.position 0(start)position 3position 5position 7position 10(dead end)position 11(end)monmonsoonsosoononsalesal

The cut positions of monsoonsale, joined by dictionary words

Text description of the diagram

Each box is a position between two letters of the hashtag monsoonsale, from position 0 before the first letter to position 11 after the last. Each arrow is a dictionary word that starts at one position and ends at another.

  • From position 0, "mon" leads to position 3 and "monsoon" leads to position 7.
  • From position 3, "so" leads to position 5 and "soon" leads to position 7.
  • From position 5, "on" leads to position 7.
  • From position 7, "sale" leads to position 11, the end, and "sal" leads to position 10.
  • No word starts at position 10, so it is a dead end.

Every path from position 0 to position 11 is one way to split the hashtag: mon so on sale, mon soon sale and monsoon sale. Three different paths reach position 7, and each continues the same way, which is the repetition a table over positions counts only once.

The brute force, and why it fails

Try every dictionary word that the rest of the string starts with, and every way on from there:

Every first word tried, with the calls counted Python · brute/split_brute.py
def splits_brute(text, words):
    """Tries every dictionary word that the rest of the text starts with, and every way on from there."""
    calls = 0

    def split_from(i):
        nonlocal calls
        calls += 1
        if i == len(text):
            return [[]]  # the empty rest has one segmentation: no more words
        found = []
        for word in words:
            if text.startswith(word, i):
                found += [[word] + rest for rest in split_from(i + len(word))]
        return found

    return split_from(0), calls


tags = [
    ("monsoonsale", ["mon", "monsoon", "soon", "so", "on", "sale", "sal", "ale"]),
    ("goldencoin", ["gold", "golden", "coins", "den"]),
]
for text, words in tags:
    found, calls = splits_brute(text, words)
    shown = "; ".join(" ".join(s) for s in found) or "no segmentation"
    print(f"{text}: {shown} ({calls} calls)")

for n in (10, 15, 20):
    found, calls = splits_brute("a" * n + "b", ["a", "aa", "aaa"])
    print(f"{n} a's and a b, words a, aa, aaa: {len(found)} segmentations after {calls:,} calls")

Output

monsoonsale: mon soon sale; mon so on sale; monsoon sale (12 calls)
goldencoin: no segmentation (3 calls)
10 a's and a b, words a, aa, aaa: 0 segmentations after 600 calls
15 a's and a b, words a, aa, aaa: 0 segmentations after 12,640 calls
20 a's and a b, words a, aa, aaa: 0 segmentations after 266,079 calls

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 split_brute.py

The hashtags are quick, but a string of a’s ending in b, with the words a, aa and aaa, has no segmentation at all and still makes the search try every way to cut the a’s: 600 calls for 10 a’s, 12,640 for 15 and 266,079 for 20, about 21 times more for every five letters. At 10,000 letters that is hopeless.

What to notice

  • Whether the rest can be split depends only on where it starts. In the diagram, three different paths reach position 7, and each continues the same way.
  • A word ends at most 20 letters after it starts, so each position has at most 20 candidate words, whatever the length of the string.
  • The output of Problem B can be exponential. Thirty a’s with the words a, aa and aaa have more than 50 million segmentations, so a listing has to know its size before it starts.

Can it be split: the table over cut positions Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • Bound the inner loop by the longest word
  • A trie: stop at the first missing prefix
  • Counting the segmentations modulo 1,000,000,007
  • Listing every segmentation, after a size check
  • The code in five languages
  • Five bugs and the smallest inputs that break them
  • Exercise
    • Count the ways to split a hashtag into words
  • Check yourself
  • A practice set with sample answers
  • Interview questions
    • Give the time and memory of the word-break table for a text of n letters and a dictionary whose longest word has L letters. Why is it safe to try only the last L cuts before each position, and what does one lookup really cost in Python?
    • A function must return every segmentation of a text, but some inputs have billions of them. Design it so that it never runs out of memory, say what it returns when the output is too large, and give its cost when the output is small.
    • A service splits millions of short hashtags a day against one dictionary of 100,000 words, many sharing prefixes. What do you build once, what do you keep per request, and how do you stop one request's memo from changing the answer of the next?
  • Key takeaways

7 runnable examples (C++, Go, Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 21 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.