472. Concatenated Words
Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words.
A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array.
Example:
Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats";
"dogcatsdog" can be concatenated by "dog", "cats" and "dog";
"ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".
Note:
- The number of elements of the given array will not exceed
10,000
- The length sum of elements in the given array will not exceed
600,000
. - All the input string will only include lower case letters.
- The returned elements order does not matter.
1、首先想到用 trie,结果 MLE。
class TrieNode{
public:
char var;
bool isword;
TrieNode* children[26];
TrieNode()
{
var = 0;
isword = 0;
memset(children, 0, sizeof(TreeNode*)*26);
}
TrieNode(char c)
{
var = c;
isword = 0;
memset(children, 0, sizeof(TreeNode*)*26);
}
};
static bool compare(string a, string b)
{
return a.size() < b.size();
}
class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words)
{
root = new TrieNode();
sort(words.begin(), words.end(), compare);
//构造字典树
for (auto word : words)
{
TrieNode* p = root;
for (int i = 0; i < word.size(); i++)
{
if ( p->children[word[i]-'a'] == 0 )
{
TrieNode *pNode = new TrieNode(word[i]);
p->children[word[i]-'a'] = pNode;
}
p = p->children[word[i]-'a'];
}
p->isword = true;
}
//挨个查找
for (auto word : words)
if (helper(word, 0))
ret.push_back(word);
return ret;
}
private:
TrieNode* root;
vector<string> ret;
bool helper(string s, int time)
{
//结束条件
if (s == "" && time >= 2)
return true;
TrieNode* p = root;
for (int i = 0; i < s.size(); i++)
{
if (p->children[s[i] - 'a'] == 0)
return false;
p = p->children[s[i] - 'a'];
if (p->isword && helper(s.substr(i + 1), time + 1))
return true;
}
return false;
}
};
2、利用原始暴力解法,竟然通过…
class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words)
{
set<string> st;
vector<string> ret;
for (auto word : words)
st.insert(word);
for (auto word : words)
{
st.erase(word);
if (search(word, st))
ret.push_back(word);
st.insert(word);
}
return ret;
}
bool search(string s, set<string>& st)
{
if (st.find(s) != st.end()) //因为已经把原始的str去除了,所以本体进来是搜不到自己的。只有进入深入拆分函数才能搜到那个时候的s
return true;
for (int i = 1; i < s.size(); i++)
{
if (st.find(s.substr(0, i)) != st.end() && search(s.substr(i), st))
return true;
}
return false;
}
};