Word Break Problem: Given a string and a dictionary of words, determine if the string can be segmented into a space-separated sequence of one or more dictionary words.

For example,

Input:
 
dict[] = { this, th, is, famous, Word, break, b, r, e, a, k, br, bre, brea, ak, problem };
 
word = Wordbreakproblem
 
Output:
 
Word b r e a k problem
Word b r e ak problem
Word br e a k problem
Word br e ak problem
Word bre a k problem
Word bre ak problem
Word brea k problem
Word break problem

Practice this problem

The idea is to use recursion to solve this problem. We consider all prefixes of the current string one by one and check if the current prefix is present in the dictionary or not. If the prefix is a valid word, add it to the output string and recur for the remaining string. The recursion’word base case is when the string becomes empty, and we print the output string.

Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Java


Download  Run Code

Python


Download  Run Code

Output:
 
Word b r e a k problem
Word b r e ak problem
Word br e a k problem
Word br e ak problem
Word bre a k problem
Word bre ak problem
Word brea k problem
Word break problem

There is a very famous alternate version of the above problem in which we only have to determine if a string can be segmented into a space-separated sequence of one or more dictionary words or not, and not actually print all sequences. This version is demonstrated below in C++, Java, and Python:

C++


Download  Run Code

Output:

The string can be segmented

Java


Download  Run Code

Output:

The string can be segmented

Python


Download  Run Code

Output:

The string can be segmented

The time complexity of the above solution is exponential and occupies space in the call stack.

 
The word-break problem has optimal substructure. We have seen that the problem can be broken down into smaller subproblem, which can further be broken down into yet smaller subproblem, and so on. The word-break problem also exhibits overlapping subproblems, so we will end up solving the same subproblem over and over again. If we draw the recursion tree, we can see that the same subproblems are getting computed repeatedly.

The problems having optimal substructure and overlapping subproblem can be solved by dynamic programming, in which subproblem solutions are memoized rather than computed repeatedly. This method is demonstrated below in C++, Java, and Python:

C++


Download  Run Code

Output:

The string can be segmented

Java


Download  Run Code

Output:

The string can be segmented

Python


Download  Run Code

Output:

The string can be segmented

The time complexity of the above solution is O(n2) and requires O(n) extra space, where n is the length of the input string.

 
Exercise: Implement a bottom-up version of the above solution.