This function word_break(s, dictionary)
receives a string s
and a set of all valid words dictionary
, and must return all possible ways the string s
can be split into valid words, if any.
For example, a string catsanddog
with dictionary {'cat', 'cats', 'sand', 'and', 'dog'}
can be broken in two ways: cats and dog
and cat sand dog
.
My solution to this recursively breaks the input string at various index (offset), and uses memoization as I realized we may be breaking at the same offset multiple times.
Here is the full code along with a test case, in Python 2.x:
def memoize(fn):
memo = {}
def wrapped_fn(*args):
if args not in memo:
memo[args] = fn(*args)
return memo[args]
return wrapped_fn
def word_break(s, dictionary):
@memoize
def _word_break(offset):
if offset == len(s):
return []
breaks_from_offset = []
if s[offset:] in dictionary:
breaks_from_offset.append([s[offset:]])
for i in range(offset+1, len(s)):
if s[offset:i] in dictionary:
for break_from_i in _word_break(i):
breaks_from_offset.append([s[offset:i]] + break_from_i)
return breaks_from_offset
return [' '.join(words) for words in _word_break(0)]
# print word_break('catsanddog', {'cat', 'cats', 'sand', 'and', 'dog'})
# -> [cat sand dog', 'cats and dog']
Based on LeetCode question Word Break II: https://leetcode.com/problems/word-break-ii/description/
As this is an "interview" algorithm question, I would love feedback that keeps that setting in mind. That said, I also appreciate any feedback to help me write more production-ready Python code :)