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 exceed10,000
The length sum of elements in the given array will not exceed600,000
.All the input string will only include lower case letters.The returned elements order does not matter.Subscribe to see which companies asked this question.
给出一个单词的集合,要求找出其中能用集合中的两个(或以上)单词组成的单词。和140题类似,只不过是单词放在了一个集合中。也是用dfs的方法,为了减少重复的计算,比如给出{“a”,"aa","aaa","aaaa"},如果已经计算好了“aa”可以用两个a组成,则用map记录下对应的数值2,。到“aaa”的时候先是遍历到单词的第一部分“a”,对第二部分“aa”用dfs,由于本来就记录好了“aa”对应的数值为2,直接返回2,这时候加起来就是3,只要数值大于1说明了这个单词是有效的答案,而不用管数值是多少了,直接返回数值,这样就能减少很多的运算。
代码:
class Solution {public: vector<string> findAllConcatenatedWordsInADict(vector<string>& words) { vector<string> res; if(words.empty()) return res; for(auto word:words) map[word] = 1; for(auto word:words) { if(dfs(word) > 1) res.push_back(word); } return res; }private: unordered_map<string, int> map; unordered_set<string> set; int dfs(string& s) { int ret = -1; if(s.empty()) return 0; if(map.find(s) != map.end() && set.find(s) != set.end()) return map[s]; for(int i = 1; i <= s.size(); ++i) { string l = s.substr(0, i), r = s.substr(i); if(map.find(l) != map.end()) { int d = dfs(r); if(d == -1) continue; ret = max(ret, map[l]+d); if(ret > 1) { map[s] = ret; set.insert(s); return ret; } } } return ret; }};
新闻热点
疑难解答