Minimum Word Break - GeeksforGeeks

09 Jul, 2021
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 sentences
in three ways, as follows:
CatMat = [ Cat Mat ]  break 1
CatMat = [ Ca tM at ] break 2
CatMat = [ C at Mat ] break 2  so the 
         output is: 1

Input : Dogcat
Output : 1
Asked in: Facebook  
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 keylenght 
  ....If we found a leaf node in trie 
        MinBreak( Trie, key, level+1, i )
Below is the implementation of above idea  
C++
Java
C#
Javascript
// C++ program to find minimum breaks needed// to break a string in dictionary words.#include <bits/stdc++.h>using namespace std; const int ALPHABET_SIZE = 26; // trie nodestruct 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 nodevoid 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 were 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 functionsint 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 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<minWordBreak){                minWordBreak = min_Break;            }            return;        }         // traverse given key(pattern)        for (int i = start; i < key.length(); i++) {            int index = key.charAt(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.minWordBreak("catmatat");         System.out.println(trie.minWordBreak);    }} // This code is contributed by Pavan Koli.
// 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
<script> // JavaScript program to find minimum breaks needed// to break a string in dictionary words. class TrieNode{    constructor()    {        this.endOfTree=false;        this.children=new Array(26);        for(let i=0;i<26;i++)            this.children[i]=null;    }} let root = new TrieNode();let minWordBreak = Number.MAX_VALUE; // If not present, inserts a key into the trie    // If the key is the prefix of trie node, just    // marks leaf nodefunction insert(key){    let length = key.length;           let index;           let pcrawl = root;           for(let i = 0; i < length; i++)        {            index = key[i].charAt(0)- 'a'.charAt(0);               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.function _minWordBreak(key){    minWordBreak = Number.MAX_VALUE;               minWordBreakUtil(root, key, 0, Number.MAX_VALUE, 0);} function minWordBreakUtil(node,key,start,min_Break,level){    let 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 (let i = start; i < key.length; i++) {            let index = key[i].charAt(0) - 'a'.charAt(0);            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 codelet keys=["cat", "mat", "ca", "ma",                    "at", "c", "dog", "og", "do" ]; let i;for (i = 0; i < keys.length ; i++)    insert(keys[i]); _minWordBreak("catmatat"); document.write(minWordBreak);  // This code is contributed by rag2127 </script>
2
 
pkoli
29AjayKumar
rag2127
Facebook
Trie
Advanced Data Structure
Strings
Facebook
Strings
Trie
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Decision Tree Introduction with example
Disjoint Set Data Structures
Red-Black Tree | Set 2 (Insert)
Insert Operation in B-Tree
AVL Tree | Set 2 (Deletion)
Reverse a string in Java
Write a program to reverse an array or string
C++ Data Types
Write a program to print all permutations of a given string
Python program to check if a string is palindrome or not