# Minimum Word Break

Given a string s, break s such that every substring of the partition can be found in the dictionary. Return the minimum break needed.

Examples:

`Given a dictionary ["Cat", "Mat", "Ca",      "tM", "at", "C", "Dog", "og", "Do"]Input :  Pattern "CatMat"Output : 1 Explanation: we can break the sentencesin three ways, as follows:CatMat = [ Cat Mat ]  break 1CatMat = [ Ca tM at ] break 2CatMat = [ C at Mat ] break 2  so the          output is: 1Input : DogcatOutput : 1`

Solution of this problem is based on the WordBreak Trie solution and level ordered graph. We start traversing given pattern and start finding a character of pattern in a trie. If we reach a node(leaf) of a trie from where we can traverse a new word of a trie(dictionary), we increment level by one and call search function for rest of the pattern character in a trie. In the end, we return minimum Break.

`  MinBreak(Trie, key, level, start = 0 )  ....  If start == key.length()      ...update min_break  for i = start to keylength   ....If we found a leaf node in trie         MinBreak( Trie, key, level+1, i )`

Below is the implementation of above idea

## C++

 `// C++ program to find minimum breaks needed` `// to break a string in dictionary words.` `#include ` `using` `namespace` `std;`   `const` `int` `ALPHABET_SIZE = 26;`   `// trie node` `struct` `TrieNode {` `    ``struct` `TrieNode* children[ALPHABET_SIZE];`   `    ``// isEndOfWord is true if the node ` `    ``// represents end of a word` `    ``bool` `isEndOfWord;` `};`   `// Returns new trie node (initialized to NULLs)` `struct` `TrieNode* getNode(``void``)` `{` `    ``struct` `TrieNode* pNode = ``new` `TrieNode;`   `    ``pNode->isEndOfWord = ``false``;`   `    ``for` `(``int` `i = 0; i < ALPHABET_SIZE; i++)` `        ``pNode->children[i] = NULL;`   `    ``return` `pNode;` `}`   `// If not present, inserts the key into the trie` `// If the key is the prefix of trie node, just` `// marks leaf node` `void` `insert(``struct` `TrieNode* root, string key)` `{` `    ``struct` `TrieNode* pCrawl = root;`   `    ``for` `(``int` `i = 0; i < key.length(); i++) {` `        ``int` `index = key[i] - ``'a'``;` `        ``if` `(!pCrawl->children[index])` `            ``pCrawl->children[index] = getNode();`   `        ``pCrawl = pCrawl->children[index];` `    ``}`   `    ``// mark last node as leaf` `    ``pCrawl->isEndOfWord = ``true``;` `}`   `// function break the string into minimum cut` `// such the every substring after breaking ` `// in the dictionary.` `void` `minWordBreak(``struct` `TrieNode* root, ` `          ``string key, ``int` `start, ``int``* min_Break, ` `                                 ``int` `level = 0)` `{` `    ``struct` `TrieNode* pCrawl = root;`   `    ``// base case, update minimum Break` `    ``if` `(start == key.length()) {        ` `        ``*min_Break = min(*min_Break, level - 1);` `        ``return``;` `    ``}`   `    ``// traverse given key(pattern)` `    ``int` `minBreak = 0;   ` `    ``for` `(``int` `i = start; i < key.length(); i++) {` `        ``int` `index = key[i] - ``'a'``;` `        ``if` `(!pCrawl->children[index])` `            ``return``;`   `        ``// if we find a condition where we can ` `        ``// move to the next word in a trie` `        ``// dictionary` `        ``if` `(pCrawl->children[index]->isEndOfWord)` `            ``minWordBreak(root, key, i + 1,` `                           ``min_Break, level + 1);`   `        ``pCrawl = pCrawl->children[index];` `    ``}` `}`   `// Driver program to test above functions` `int` `main()` `{` `    ``string dictionary[] = { ``"Cat"``, ``"Mat"``,` `   ``"Ca"``, ``"Ma"``, ``"at"``, ``"C"``, ``"Dog"``, ``"og"``, ``"Do"` `};` `    ``int` `n = ``sizeof``(dictionary) / ``sizeof``(dictionary[0]);` `    ``struct` `TrieNode* root = getNode();`   `    ``// Construct trie` `    ``for` `(``int` `i = 0; i < n; i++)` `        ``insert(root, dictionary[i]);` `    ``int` `min_Break = INT_MAX;`   `    ``minWordBreak(root, ``"CatMatat"``, 0, &min_Break, 0);` `    ``cout << min_Break << endl;` `    ``return` `0;` `}`

## Java

 `// Java program to find minimum breaks needed` `// to break a string in dictionary words.` `public` `class` `Trie {`   `TrieNode root = ``new` `TrieNode();` `int` `minWordBreak = Integer.MAX_VALUE;`   `    ``// Trie node` `    ``class` `TrieNode {` `        ``boolean` `endOfTree;` `        ``TrieNode children[] = ``new` `TrieNode[``26``];` `        ``TrieNode(){` `            ``endOfTree = ``false``;` `            ``for``(``int` `i=``0``;i<``26``;i++){` `                ``children[i]=``null``;` `            ``}` `        ``}` `    ``}`   `    ``// If not present, inserts a key into the trie` `    ``// If the key is the prefix of trie node, just` `    ``// marks leaf node` `    ``void` `insert(String key){` `        ``int` `length = key.length();`   `        ``int` `index;`   `        ``TrieNode pcrawl = root;`   `        ``for``(``int` `i = ``0``; i < length; i++)` `        ``{` `            ``index = key.charAt(i)- ``'a'``;`   `            ``if``(pcrawl.children[index] == ``null``)` `                ``pcrawl.children[index] = ``new` `TrieNode();`   `            ``pcrawl = pcrawl.children[index];` `        ``}` `        `  `        ``// mark last node as leaf` `        ``pcrawl.endOfTree = ``true``;`   `    ``}`   `    ``// function break the string into minimum cut` `    ``// such the every substring after breaking ` `    ``// in the dictionary.` `    ``void` `minWordBreak(String key)` `    ``{` `        ``minWordBreak = Integer.MAX_VALUE;` `        `  `        ``minWordBreakUtil(root, key, ``0``, Integer.MAX_VALUE, ``0``);` `    ``}` `    `  `    ``void` `minWordBreakUtil(TrieNode node, String key,` `                ``int` `start, ``int` `min_Break, ``int` `level)` `    ``{` `        ``TrieNode pCrawl = node;`   `        ``// base case, update minimum Break` `        ``if` `(start == key.length()) {` `            ``min_Break = Math.min(min_Break, level - ``1``);` `            ``if``(min_Break

## Python3

 `# Python program to find minimum breaks needed` `# to break a string in dictionary words.`   `import` `sys`     `class` `TrieNode:`   `    ``def` `__init__(``self``):` `    `  `        ``self``.endOfTree ``=` `False` `        ``self``.children ``=` `[``None` `for` `i ``in` `range``(``26``)]` `        `      `root ``=` `TrieNode()` `minWordBreak ``=` `sys.maxsize`   `# If not present, inserts a key into the trie` `    ``# If the key is the prefix of trie node, just` `    ``# marks leaf node` `def` `insert(key):`   `    ``global` `root,minWordBreak`   `    ``length ``=` `len``(key)`   `    ``pcrawl ``=` `root`   `    ``for` `i ``in` `range``(length):`   `        ``index ``=` `ord``(key[i])``-` `ord``(``'a'``)`   `        ``if``(pcrawl.children[index] ``=``=` `None``):` `            ``pcrawl.children[index] ``=` `TrieNode()` `        ``pcrawl ``=` `pcrawl.children[index]` `        `  `        ``# mark last node as leaf` `        ``pcrawl.endOfTree ``=` `True`   `# function break the string into minimum cut` `# such the every substring after breaking` `# in the dictionary.` `def` `_minWordBreak(key):`   `    ``global` `minWordBreak`   `    ``minWordBreak ``=` `sys.maxsize` `        `  `    ``minWordBreakUtil(root, key, ``0``, sys.maxsize, ``0``)`   `def` `minWordBreakUtil(node,key,start,min_Break,level):`   `    ``global` `minWordBreak,root`   `    ``pCrawl ``=` `node`   `    ``# base case, update minimum Break` `    ``if` `(start ``=``=` `len``(key)):` `            ``min_Break ``=` `min``(min_Break, level ``-` `1``)` `            ``if``(min_Break

## C#

 `// C# program to find minimum breaks needed ` `// to break a string in dictionary words.` `using` `System; `   `class` `Trie` `{ `   `    ``TrieNode root = ``new` `TrieNode(); ` `    ``int` `minWordBreak = ``int``.MaxValue ; `   `    ``// Trie node ` `    ``public` `class` `TrieNode ` `    ``{ ` `        ``public` `bool` `endOfTree; ` `        ``public` `TrieNode []children = ``new` `TrieNode[26]; ` `        ``public` `TrieNode()` `        ``{ ` `            ``endOfTree = ``false``; ` `            ``for``(``int` `i = 0; i < 26; i++)` `            ``{ ` `                ``children[i] = ``null``; ` `            ``} ` `        ``} ` `    ``} `   `    ``// If not present, inserts a key ` `    ``// into the trie If the key is the ` `    ``// prefix of trie node, just marks leaf node ` `    ``void` `insert(String key)` `    ``{ ` `        ``int` `length = key.Length; `   `        ``int` `index; `   `        ``TrieNode pcrawl = root; `   `        ``for``(``int` `i = 0; i < length; i++) ` `        ``{ ` `            ``index = key[i]- ``'a'``; `   `            ``if``(pcrawl.children[index] == ``null``) ` `                ``pcrawl.children[index] = ``new` `TrieNode(); `   `            ``pcrawl = pcrawl.children[index]; ` `        ``} ` `        `  `        ``// mark last node as leaf ` `        ``pcrawl.endOfTree = ``true``; `   `    ``} `   `    ``// function break the string into minimum cut ` `    ``// such the every substring after breaking ` `    ``// in the dictionary. ` `    ``void` `minWordBreaks(String key) ` `    ``{ ` `        ``minWordBreak = ``int``.MaxValue; ` `        ``minWordBreakUtil(root, key, 0, ``int``.MaxValue, 0); ` `    ``} ` `    `  `    ``void` `minWordBreakUtil(TrieNode node, String key, ` `                ``int` `start, ``int` `min_Break, ``int` `level) ` `    ``{ ` `        ``TrieNode pCrawl = node; `   `        ``// base case, update minimum Break ` `        ``if` `(start == key.Length) ` `        ``{ ` `            ``min_Break = Math.Min(min_Break, level - 1); ` `            ``if``(min_Break < minWordBreak)` `            ``{ ` `                ``minWordBreak = min_Break; ` `            ``} ` `            ``return``; ` `        ``} `   `        ``// traverse given key(pattern) ` `        ``for` `(``int` `i = start; i < key.Length; i++) ` `        ``{ ` `            ``int` `index = key[i] - ``'a'``; ` `            ``if` `(pCrawl.children[index]==``null``) ` `                ``return``; `   `            ``// if we find a condition were we can ` `            ``// move to the next word in a trie ` `            ``// dictionary ` `            ``if` `(pCrawl.children[index].endOfTree) ` `            ``{ ` `                ``minWordBreakUtil(root, key, i + 1, ` `                        ``min_Break, level + 1); ` `            ``} ` `            ``pCrawl = pCrawl.children[index]; ` `        ``} ` `    ``} `   `    ``// Driver code ` `    ``public` `static` `void` `Main(String[] args) ` `    ``{ ` `        ``String []keys = {``"cat"``, ``"mat"``, ``"ca"``, ``"ma"``, ` `                    ``"at"``, ``"c"``, ``"dog"``, ``"og"``, ``"do"` `}; `   `        ``Trie trie = ``new` `Trie(); `   `        ``// Construct trie ` `        ``int` `i; ` `        ``for` `(i = 0; i < keys.Length ; i++) ` `            ``trie.insert(keys[i]); ` `        `  `        ``trie.minWordBreaks(``"catmatat"``); ` `        ``Console.WriteLine(trie.minWordBreak); ` `    ``} ` `} `   `// This code is contributed by 29AjayKumar`

## Javascript

 ``

Output

```2

```

Time Complexity: O(n*n*L) where n is the length of the input string and L is the maximum length of word in the dictionary.
Auxiliary Space: O(ALPHABET_SIZE^L+n*L)

### Approach 2: Using Dynamic Programming

• We maintain an array dp where dp[i] represents the minimum number of breaks needed to break the substring s[0…i-1] into dictionary words.
• We initialize dp[0] = 0 since the empty string can be broken into zero words.
• For each position i in the string, we iterate over all dictionary words and check if the substring ending at position i matches the current dictionary word.
• If it does, we update dp[i] to be the minimum of dp[i] and dp[i – len] + 1, where len is the length of the current dictionary word.
• Finally, we return dp[n] – 1, where n is the length of the input string, since the number of breaks needed is one less than the number of words.

## C++

 `#include ` `using` `namespace` `std;`   `const` `int` `INF = 1e9;`   `int` `minWordBreak(string s, vector& dict) {` `    ``int` `n = s.length();` `    ``vector<``int``> dp(n + 1, INF);` `    ``dp[0] = 0;`   `    ``for` `(``int` `i = 1; i <= n; i++) {` `        ``for` `(string word : dict) {` `            ``int` `len = word.length();` `            ``if` `(i >= len && s.substr(i - len, len) == word) {` `                ``dp[i] = min(dp[i], dp[i - len] + 1);` `            ``}` `        ``}` `    ``}`   `    ``return` `dp[n] - 1;` `}`   `int` `main() {` `    ``vector dict = {``"Cat"``, ``"Mat"``, ``"Ca"``, ``"Ma"``, ``"at"``, ``"C"``, ``"Dog"``, ``"og"``, ``"Do"``};` `    ``string s = ``"CatMatat"``;` `    ``cout << minWordBreak(s, dict) << endl;` `    ``return` `0;` `}`

## Java

 `import` `java.util.*;`   `public` `class` `WordBreak {` `    ``static` `final` `int` `INF = (``int``)1e9;`   `    ``public` `static` `int` `minWordBreak(String s,` `                                   ``List dict)` `    ``{` `        ``int` `n = s.length();` `        ``int``[] dp = ``new` `int``[n + ``1``];` `        ``Arrays.fill(dp, INF);` `        ``dp[``0``] = ``0``;`   `        ``for` `(``int` `i = ``1``; i <= n; i++) {` `            ``for` `(String word : dict) {` `                ``int` `len = word.length();` `                ``if` `(i >= len` `                    ``&& s.substring(i - len, i)` `                           ``.equals(word)) {` `                    ``dp[i]` `                        ``= Math.min(dp[i], dp[i - len] + ``1``);` `                ``}` `            ``}` `        ``}`   `        ``return` `dp[n] - ``1``;` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``List dict` `            ``= Arrays.asList(``"Cat"``, ``"Mat"``, ``"Ca"``, ``"Ma"``, ``"at"``,` `                            ``"C"``, ``"Dog"``, ``"og"``, ``"Do"``);` `        ``String s = ``"CatMatat"``;` `        ``System.out.println(minWordBreak(s, dict));` `    ``}` `}`

## Python3

 `def` `min_word_break(s, ``dict``):` `    ``n ``=` `len``(s)` `    ``dp ``=` `[``float``(``'inf'``)] ``*` `(n ``+` `1``)  ``# Initialize a list to store minimum word breaks needed` `    ``dp[``0``] ``=` `0`  `# No breaks needed for an empty string`   `    ``for` `i ``in` `range``(``1``, n ``+` `1``):` `        ``for` `word ``in` `dict``:` `            ``length ``=` `len``(word)` `            ``if` `i >``=` `length ``and` `s[i ``-` `length:i] ``=``=` `word:` `                ``# Check if the substring from i-length to i matches a word in the dictionary` `                ``dp[i] ``=` `min``(dp[i], dp[i ``-` `length] ``+` `1``)` `                ``# Update the minimum word breaks needed at position i`   `    ``return` `dp[n] ``-` `1`  `# Return the minimum word breaks needed for the entire string`   `def` `main():` `    ``dict` `=` `[``"Cat"``, ``"Mat"``, ``"Ca"``, ``"Ma"``, ``"at"``, ``"C"``, ``"Dog"``, ``"og"``, ``"Do"``]` `    ``s ``=` `"CatMatat"` `    ``min_breaks ``=` `min_word_break(s, ``dict``)` `    ``print``(f``"The minimum word breaks needed: {min_breaks}"``)`   `if` `__name__ ``=``=` `"__main__"``:` `    ``main()` `# This code is contributed by shivamgupta0987654321`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG` `{` `    ``const` `int` `INF = 1000000000;` `    ``public` `static` `int` `MinWordBreak(``string` `s, List<``string``> dict)` `    ``{` `        ``int` `n = s.Length;` `        ``int``[] dp = ``new` `int``[n + 1];` `        ``for` `(``int` `i = 0; i <= n; i++)` `            ``dp[i] = INF;` `        ``dp[0] = 0;` `        ``for` `(``int` `i = 1; i <= n; i++)` `        ``{` `            ``foreach` `(``string` `word ``in` `dict)` `            ``{` `                ``int` `len = word.Length;` `                ``if` `(i >= len && s.Substring(i - len, len) == word)` `                ``{` `                    ``dp[i] = Math.Min(dp[i], dp[i - len] + 1);` `                ``}` `            ``}` `        ``}` `        ``return` `dp[n] - 1;` `    ``}` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``List<``string``> dict = ``new` `List<``string``> { ``"Cat"``, ``"Mat"``, ``"Ca"``, ``"Ma"``, ``"at"``, ``"C"``, ``"Dog"``, ``"og"``, ``"Do"` `};` `        ``string` `s = ``"CatMatat"``;` `        ``int` `result = MinWordBreak(s, dict);` `        ``Console.WriteLine(result);` `    ``}` `}`

## Javascript

 `// Define a constant for infinity, which will be used as an initial value in the DP array` `const INF = 1e9;`   `// Function to find the minimum word break count` `function` `minWordBreak(s, dict) {` `    ``const n = s.length; ``// Length of the input string` `    ``const dp = ``new` `Array(n + 1).fill(INF); ``// Initialize a DP array with initially infinite values` `    ``dp[0] = 0; ``// The base case: No breaks needed for an empty string`   `    ``// Iterate over the characters in the input string` `    ``for` `(let i = 1; i <= n; i++) {` `        ``// Iterate over the words in the dictionary` `        ``for` `(const word of dict) {` `            ``const len = word.length; ``// Length of the current dictionary word`   `            ``// Check if the current substring (ending at position i) matches the dictionary word` `            ``if` `(i >= len && s.substring(i - len, i) === word) {` `                ``// If it matches, update the DP array with the minimum break count` `                ``dp[i] = Math.min(dp[i], dp[i - len] + 1);` `            ``}` `        ``}` `    ``}`   `    ``return` `dp[n] - 1; ``// Subtract 1 to get the minimum break count` `}`   `// Driver code` `const dict = [``"Cat"``, ``"Mat"``, ``"Ca"``, ``"Ma"``, ``"at"``, ``"C"``, ``"Dog"``, ``"og"``, ``"Do"``];` `const s = ``"CatMatat"``;` `console.log(``"Minimum Word Break Count:"``, minWordBreak(s, dict));`

Output

```2

```

Note that this code has a time complexity of O(n*m), where n is the length of the input string and m is the size of the dictionary. This is because we iterate over all positions in the string and for each position, we iterate over all words in the dictionary.

If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!