# Word Break Problem | DP-32 | Set – 2

• Difficulty Level : Hard
• Last Updated : 22 Jun, 2022

Given a non-empty sequence S and a dictionary dict[] containing a list of non-empty words, print all possible ways to break the sentence in individual dictionary words.
Examples:

Input: S = “catsanddog”
dict[] = {“cat”, “cats”, “and”, “sand”, “dog”}
Output:
“cats and dog”
“cat sand dog”
Input: S = “pineapplepenapple”
dict[] = {“apple”, “pen”, “applepen”, “pine”, “pineapple”}
Output:
“pine apple pen apple”
“pineapple pen apple”
“pine applepen apple”

A similar problem to this is discussed in this article, where the task is to check that is there any solution such that the sequence can be broken into the dictionary words.
Approach: The idea is to check for every substring starting from any position I , such that it ends at the length of the string which is present in the dictionary then simply recurse for the substring [0, I]. Meanwhile, store the overlapping subproblems for each substring to avoid the computation of the subproblem again. Overlapping subproblems can be shown as follows – Below is the implementation of the above approach:

## C++

 `// C++ implementation to break``// a sequence into the words of``// the dictionary` `#include ` `using` `namespace` `std;` `// Unordered_map used for storing``// the sentences the key string``// can be broken into``unordered_map > mp;` `// Unordered_set used``// to store the dictionary.``unordered_set dict;` `// Utility function used for``// printing the obtained result``void` `printResult(vector A)``{``    ``for` `(``int` `i = 0; i < A.size(); i++)``        ``cout << A[i] << ``'\n'``;``}` `// Utility function for``// appending new words``// to already existing strings``vector combine(``     ``vector prev, string word){``    ` `    ``// Loop to find the append string``    ``// which can be broken into``    ``for` `(``int` `i = 0; i < prev.size(); i++) {``        ``prev[i] += ``" "` `+ word;``    ``}``    ``return` `prev;``}` `// Utility function for word Break``vector wordBreakUtil(string s)``{  ``    ``// Condition to check if the``    ``// subproblem is already computed``    ``if` `(mp.find(s) != mp.end())``        ``return` `mp[s];``    ``vector res;``    ` `    ``// If the whole word is a dictionary``    ``// word then directly append into``    ``// the result array for the string``    ``if` `(dict.find(s) != dict.end())``        ``res.push_back(s);``    ` `    ``// Loop to iterate over the substring``    ``for` `(``int` `i = 1; i < s.length(); i++) {``        ``string word = s.substr(i);``        ` `        ``// If the substring is present into``        ``// the dictionary then recurse for``        ``// other substring of the string``        ``if` `(dict.find(word) != dict.end()) {``            ``string rem = s.substr(0, i);``            ``vector prev =``             ``combine(wordBreakUtil(rem), word);``            ``res.insert(res.end(),``                 ``prev.begin(), prev.end());``        ``}``    ``}``    ` `    ``// Store the subproblem``    ``// into the map``    ``mp[s] = res;``    ``return` `res;``}` `// Master wordBreak function converts``// the string vector to unordered_set``vector wordBreak(string s,``             ``vector& wordDict)``{``    ``// Clear the previous stored data``    ``mp.clear();``    ``dict.clear();``    ``dict.insert(wordDict.begin(), wordDict.end());``    ``return` `wordBreakUtil(s);``}` `// Driver Code``int` `main()``{``    ``vector wordDict1 = {``        ``"cat"``, ``"cats"``, ``"and"``, ``"sand"``, ``"dog"` `};``    ``printResult(wordBreak(``"catsanddog"``, wordDict1));``    ``return` `0;``}`

## Java

 `import` `java.util.*;``import` `java.io.*;` `// Java program for the above approach``class` `GFG{` `  ``// Unordered_map used for storing``  ``// the sentences the key String``  ``// can be broken into``  ``static` `TreeMap> mp =``    ``new` `TreeMap>();` `  ``// Unordered_set used``  ``// to store the dictionary.``  ``static` `TreeSet dict = ``new` `TreeSet();` `  ``// Utility function used for``  ``// printing the obtained result``  ``static` `void` `printResult(ArrayList A)``  ``{``    ``for` `(``int` `i = ``0` `; i < A.size() ; i++){``      ``System.out.println(A.get(i));``    ``}``  ``}` `  ``// Utility function for``  ``// appending new words``  ``// to already existing strings``  ``static` `ArrayList combine(ArrayList prev, String word){` `    ``// Loop to find the append String``    ``// which can be broken into``    ``for` `(``int` `i = ``0` `; i < prev.size() ; i++) {``      ``prev.set(i, prev.get(i) + ``" "` `+ word);``    ``}``    ``return` `prev;``  ``}` `  ``// Utility function for word Break``  ``static` `ArrayList wordBreakUtil(String s)``  ``{` `    ``// Condition to check if the``    ``// subproblem is already computed``    ``if` `(mp.containsKey(s)){``      ``return` `mp.get(s);``    ``}``    ``ArrayList res = ``new` `ArrayList();` `    ``// If the whole word is a dictionary``    ``// word then directly append into``    ``// the result array for the String``    ``if` `(dict.contains(s))``      ``res.add(s);` `    ``// Loop to iterate over the substring``    ``for` `(``int` `i = ``1` `; i < s.length() ; i++) {``      ``String word = s.substring(i);` `      ``// If the substring is present into``      ``// the dictionary then recurse for``      ``// other substring of the String``      ``if` `(dict.contains(word)) {``        ``String rem = s.substring(``0``, i);``        ``ArrayList prev =  combine(wordBreakUtil(rem), word);``        ``for``(``int` `j = ``0` `; j < prev.size() ; j++){``          ``res.add(prev.get(j));``        ``}``      ``}``    ``}` `    ``// Store the subproblem``    ``// into the map``    ``mp.put(s, res);``    ``return` `res;``  ``}` `  ``// Master wordBreak function converts``  ``// the String vector to unordered_set``  ``static` `ArrayList wordBreak(String s, ArrayList wordDict)``  ``{``    ``// Clear the previous stored data``    ``mp.clear();``    ``dict.clear();``    ``dict.addAll(wordDict);``    ``return` `wordBreakUtil(s);``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String args[])``  ``{``    ``ArrayList wordDict1 = ``new` `ArrayList(``      ``List.of(``"cat"``, ``"cats"``, ``"and"``, ``"sand"``, ``"dog"``)``    ``);``    ``printResult(wordBreak(``"catsanddog"``, wordDict1));``  ``}``}` `// This code is contributed by subhamgoyal2014.`

## Python3

 `# Python3 implementation to break``# a sequence into the words of``# the dictionary`` ` `# Unordered_map used for storing``# the sentences the key string``# can be broken into``mp ``=` `dict``()`` ` `# Unordered_set used``# to store the dictionary.``dict_t ``=` `set``()`` ` `# Utility function used for``# printing the obtained result``def` `printResult(A):` `    ``for` `i ``in` `range``(``len``(A)):``        ``print``(A[i])`` ` `# Utility function for``# appending new words``# to already existing strings``def` `combine( prev, word):``     ` `    ``# Loop to find the append string``    ``# which can be broken into``    ``for` `i ``in` `range``(``len``(prev)):``    ` `        ``prev[i] ``+``=` `" "` `+` `word;``    ` `    ``return` `prev;` `# Utility function for word Break``def` `wordBreakUtil(s):` `    ``# Condition to check if the``    ``# subproblem is already computed``    ``if` `(s ``in` `mp):``        ``return` `mp[s];``    ` `    ``res ``=` `[]``     ` `    ``# If the whole word is a dictionary``    ``# word then directly append into``    ``# the result array for the string``    ``if` `(s ``in` `dict_t):``        ``res.append(s);``     ` `    ``# Loop to iterate over the substring``    ``for` `i ``in` `range``(``1``, ``len``(s)):``        ` `        ``word ``=` `s[i:];``         ` `        ``# If the substring is present into``        ``# the dictionary then recurse for``        ``# other substring of the string``        ``if` `(word ``in` `dict_t):``            ` `            ``rem ``=` `s[:i]``            ``prev ``=` `combine(wordBreakUtil(rem), word);``            ``for` `i ``in` `prev:``                ``res.append(i)``     ` `    ``# Store the subproblem``    ``# into the map``    ``#res is an reference so we need to assign an reference to something if its keep on changing``    ``#res values changes after it start going through combine method``    ``#you can check if you had a doubt so here we just clone res``    ``x``=``[]``    ``for` `i ``in` `res:``      ``x.append(i)``    ``mp[s] ``=` `x;``    ``return` `res;`` ` `# Master wordBreak function converts``# the string vector to unordered_set``def` `wordBreak(s,  wordDict):` `    ``# Clear the previous stored data``    ``mp.clear();``    ``dict_t.clear();``    ``for` `i ``in` `wordDict:``        ``dict_t.add(i)``    ``return` `wordBreakUtil(s);` `# Driver Code``if` `__name__``=``=``'__main__'``:` `    ``wordDict1 ``=` `[``"cat"``, ``"cats"``, ``"and"``, ``"sand"``, ``"dog"` `]``    ``printResult(wordBreak(``"catsanddog"``, wordDict1));` `# This code is contributed by rutvik_56`

## Javascript

 ``

Output:

```cat sand dog
cats and dog```

Time Complexity: O(2^N), where N is the length of the given string.
Auxiliary Space: O(S + N). where S is the sum of all characters of wordDict1.

My Personal Notes arrow_drop_up