Can the String Be Segmented
Given a dictionary of words, print yes if the string can be split into a sequence of
dictionary words, or no otherwise. Words may be reused any number of times, and every
character must be covered.
leetcode, words leet code -> yes
catsandog, words cats dog sand and cat -> no
aaaaaaa, words aaa aaaa -> yes aaa + aaaa
## Why greedy fails
Taking the longest matching word at each position is wrong, and catsandog shows why:
cats matches, then and, then og is not a word. Backing up to cat, then sand,
then og again fails. The answer is no, but the greedy would have to try both to know
that, and on inputs where the answer is yes the greedy can commit to a prefix that
dooms the rest.
aaaaaaa with aaa and aaaa is the positive version: longest-first takes aaaa then
aaa, which works, and shortest-first takes aaa aaa and is then stuck with one a.
Neither order is reliable.
## The recurrence
ok[i] = can the first i characters be segmented
ok[0] = true
ok[i] = true if some j < i has ok[j] and s[j..i-1] is a word
Each position is decided once and reused by every later position, which is what makes this linear in the number of (start, end) pairs rather than exponential in the number of splits. The exponential recursion and this table differ only in that the table remembers.
## Why ok[0] = true is the whole base case
ok[0] says the empty prefix is segmentable, by the empty sequence of words. Every other
entry is built from it, and getting it wrong makes the entire table false.
It is worth being able to say what ok[0] = true MEANS rather than treating it as a magic
initialiser, because the same question decides problem 491's initialisation and gets a
different answer there.
## Implementation notes
Put the dictionary in a hash set, so the membership test is O(length of the candidate)
rather than a scan of the word list.
The inner loop can stop at the longest word length: a candidate longer than every
dictionary word cannot match. That turns O(n^2) substring tests into
O(n * maxWordLength), which matters when n is large and the words are short.
## Boundaries
a with the single word a answers yes, and with the single word b answers no.
Those are the smallest cases in each direction.
abcd with ab abc cd answers yes via ab + cd, and it is the case where the FIRST
matching word at position 0 is not part of any solution if you happened to try abc
first. The table tries all of them.
## Cost
Time O(n * maxWordLength) substring tests, each O(maxWordLength). Space O(n) plus the
dictionary.