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.
参考资料:here。
class Solution {
private:
struct Node {
bool end;
vector<Node*> next;
Node() :end(false){
next = vector<Node*>(26, NULL);
}
};
Node *root;
void addWord(string &s) {
Node* curr = root;
for (char c : s) {
int idx = c - 'a';
if (curr->next[idx] == NULL)
curr->next[idx] = new Node();
curr = curr->next[idx];
}
curr->end = true;
}
bool helper(string &word, int start, int count) {
Node* curr = root;
for (int i = start; i < word.size(); i++) {
int idx = word[i] - 'a';
if (curr->next[idx] == NULL) return false;
if (curr->next[idx]->end) {
if (i == word.size() - 1) return count >= 1;
if (helper(word, i + 1, count + 1)) return true;
}
curr = curr->next[idx];
}
return false;
}
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
vector<string> ans;
root = new Node();
for (string word : words) addWord(word);
for (string word : words) {
if (helper(word, 0, 0)) ans.push_back(word);
}
return ans;
}
};