网上查了下,好像可以用DP做...
但是我这种DP弱...感觉只要是DP就做不来TAT(等下再看看DP的题解
其实这个可以用Trie做.
把dict的词全部建立一颗Trie
然后呢,从给定的字符串开始走。。。
遍历一下Trie,如果遇到isWord,就说明这个前缀在dict里面啦。
那么在这个位置做个标记。
然后扫描这些做了标记的位置(肯定是在后面啦。。。从前往后就ok了。。。
继续从下一个字符开始作为起点,做如上处理。
如果最后s.size()-1这个位置也是结尾的字符,那么就说明这个是ok的!返回true
class TrieNode{ public: TrieNode* childs[26]; bool isWord; TrieNode():isWord(false){ for(int i = 0 ; i < 26 ; i++) childs[i] = nullptr; } void insert(const string& str){ int size = str.size(); TrieNode* curr = this; for(int i = 0 ; i < size ; i++){ if(curr -> childs[str[i] - 'a'] == nullptr){ curr -> childs[str[i] - 'a'] = new TrieNode(); }else{ //do nothing } curr = curr -> childs[str[i] - 'a']; } curr -> isWord = true; } ~TrieNode(){ for(int i = 0 ;i < 26 ; i++) delete childs[i]; } }; class Solution { public: bool wordBreak(string s, unordered_set<string> &dict) { TrieNode* root = new TrieNode(); for(auto i = dict.begin() ; i != dict.end() ; i++){ root -> insert(*i); } vector<bool> v(s.size() , false); findMatch(s , root , 0 , v); int size = s.size(); for(int i = 0 ; i < size ; i++) if(v[i]) findMatch(s , root , i + 1 , v); return v[size - 1]; } void findMatch(const string& str , TrieNode* root , int start , vector<bool>& v){ int size = str.size(); TrieNode* curr = root; for(int i = start ; i < size ; i++){ if(curr -> childs[str[i] - 'a'] != nullptr){ curr = curr -> childs[str[i] - 'a']; if(curr -> isWord){ v[i] = true; } }else{ break; } } } };
by 1957