📜  最小断字

📅  最后修改于: 2021-04-17 09:41:32             🧑  作者: Mango

给定字符串s,请断开s,以便可以在字典中找到分区的每个子字符串。返回所需的最小休息时间。
例子:

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

询问: Facebook

该问题的解决方案基于WordBreak Trie解决方案和级别排序图。我们开始遍历给定的模式,并开始在特里中找到模式的字符。如果我们到达一个trie的节点(叶),从那里可以遍历一个trie(字典)的新单词,我们将级别增加1,并为trie中的其余模式字符调用搜索函数。最后,我们返回最小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 )

以下是上述想法的实现

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 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 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


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


输出:
2