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:

  1. The number of elements of the given array will not exceed 10,000
  2. The length sum of elements in the given array will not exceed 600,000.
  3. All the input string will only include lower case letters.
  4. The returned elements order does not matter.

这道题给了一个由单词组成的数组,某些单词是可能由其他的单词组成的,让我们找出所有这样的单词。这道题跟之前那道Word Break十分类似,我们可以对每一个单词都调用之前那题的方法,我们首先把所有单词都放到一个unordered_set中,这样可以快速找到某个单词是否在数组中存在。对于当前要判断的单词,我们先将其从set中删去,然后调用之前的Word Break的解法,具体讲解可以参见之前的帖子。如果是可以拆分,那么我们就存入结果res中,参见代码如下:

解法一:

class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
if (words.size() <= ) return {};
vector<string> res;
unordered_set<string> dict(words.begin(), words.end());
for (string word : words) {
dict.erase(word);
int len = word.size();
if (len == ) continue;
vector<bool> v(len + , false);
v[] = true;
for (int i = ; i < len + ; ++i) {
for (int j = ; j < i; ++j) {
if (v[j] && dict.count(word.substr(j, i - j))) {
v[i] = true;
break;
}
}
}
if (v.back()) res.push_back(word);
dict.insert(word);
}
return res;
}
};

下面这种方法跟上面的方法很类似,不同的是判断每个单词的时候不用将其移除set,而是在判断的过程中加了判断,使其不会判断单词本身是否在集合set中存在,而且由于对单词中子字符串的遍历顺序不同,加了一些优化在里面,使得其运算速度更快一些,参见代码如下:

解法二:

class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
vector<string> res;
unordered_set<string> dict(words.begin(), words.end());
for (string word : words) {
int n = word.size();
if (n == ) continue;
vector<bool> dp(n + , false);
dp[] = true;
for (int i = ; i < n; ++i) {
if (!dp[i]) continue;
for (int j = i + ; j <= n; ++j) {
if (j - i < n && dict.count(word.substr(i, j - i))) {
dp[j] = true;
}
}
if (dp[n]) {res.push_back(word); break;}
}
}
return res;
}
};

下面这种方法是递归的写法,其中递归函数中的cnt表示有其他单词组成的个数,至少得由其他两个单词组成才符合题意,参见代码如下:

解法三:

class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
vector<string> res;
unordered_set<string> dict(words.begin(), words.end());
for (string word : words) {
if (word.empty()) continue;
if (helper(word, dict, , )) {
res.push_back(word);
}
}
return res;
}
bool helper(string& word, unordered_set<string>& dict, int pos, int cnt) {
if (pos >= word.size() && cnt >= ) return true;
for (int i = ; i <= (int)word.size() - pos; ++i) {
string t = word.substr(pos, i);
if (dict.count(t) && helper(word, dict, pos + i, cnt + )) {
return true;
}
}
return false;
}
};

类似题目:

Word Break

参考资料:

https://discuss.leetcode.com/topic/72393/c-772-ms-dp-solution

https://discuss.leetcode.com/topic/72433/c-600ms-20-lines-of-code-dfs-solution-is-there-any-way-to-optimize

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Concatenated Words 连接的单词的更多相关文章

  1. 472 Concatenated Words 连接的单词

    详见:https://leetcode.com/problems/concatenated-words/description/ C++: class Solution { public: vecto ...

  2. [LeetCode] Valid Word Square 验证单词平方

    Given a sequence of words, check whether it forms a valid word square. A sequence of words forms a v ...

  3. [LeetCode] Valid Word Abbreviation 验证单词缩写

    Given a non-empty string s and an abbreviation abbr, return whether the string matches with the give ...

  4. [LeetCode] Shortest Word Distance 最短单词距离

    Given a list of words and two words word1 and word2, return the shortest distance between these two ...

  5. [LeetCode] Short Encoding of Words 单词集的短编码

    Given a list of words, we may encode it by writing a reference string S and a list of indexes A. For ...

  6. [LeetCode] Expressive Words 富于表现力的单词

    Sometimes people repeat letters to represent extra feeling, such as "hello" -> "he ...

  7. LeetCode 79 Word Search(单词查找)

    题目链接:https://leetcode.com/problems/word-search/#/description 给出一个二维字符表,并给出一个String类型的单词,查找该单词是否出现在该二 ...

  8. LeetCode 290 Word Pattern(单词模式)(istringstream、vector、map)(*)

    翻译 给定一个模式,和一个字符串str.返回str是否符合同样的模式. 这里的符合意味着全然的匹配,所以这是一个一对多的映射,在pattern中是一个字母.在str中是一个为空的单词. 比如: pat ...

  9. LeetCode 1255 得分最高的单词集合 Maximum Score Words Formed by Letters

    地址 https://leetcode-cn.com/problems/maximum-score-words-formed-by-letters/ 题目描述你将会得到一份单词表 words,一个字母 ...

随机推荐

  1. 由objC运行时所想到的。。。

    objC语言不仅仅有着面向对象的特点(封装,继承和多态),也拥有类似脚本语言的灵活(运行时),这让objC有着很多奇特的功能-可在运行时添加给类或对象添加方法,甚至可以添加类方法,甚至可以动态创建类. ...

  2. GeoServer中WMS、WFS的请求规范

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 1.1WMS简介 Web地图服务(WMS)利用具有地理空间位置 ...

  3. EF 在controller弹出提示消息

    第一种方式: return Content("<script>alert('此名称课程再次班级中已经存在!');window.location.href = 'Course/Cr ...

  4. HTML5简介

    HTML5简介 HTML5是HTML的最新修订标准.2014年10月29日,万维网联盟(W3C)宣布,经过8年的努力,HTML5标准规范制定完成. HTML5的设计目的是在移动设备上使用多媒体. HT ...

  5. ef

    现阶段使用回溯 entityframework作为.net平台自己的一个orm的框架,之前在项目中也有使用,主要采用了table和model first的方式,此两种感觉使用上也是大同小异.在项目中经 ...

  6. Spring 实现数据库读写分离

    随着互联网的大型网站系统访问量的增高,数据库访问压力方面不断的显现而出,所以许多公司在数据库层面采用读写分离技术,也就是一个master,多个slave.master负责数据的实时更新或实时查询,而s ...

  7. 织梦cms常用标签

    dedecms简介:织梦内容管理系统(DedeCms) 以简单.实用.开源而闻名,是国内知名的PHP开源网站管理系统,也是使用用户较多的PHP类CMS系统,在经历多年的发展,目前的版本无论在功能,还是 ...

  8. instanceof 运算符

    java中的instanceof=======>二元运算符 用法: result = object instanceof class 参数: result 是boolean类型 object 是 ...

  9. 详细介绍Mysql各种存储引擎的特性以及如何选择存储引擎

    最近业务上有要求,要实现类似oracle 的dblink   linux版本 Server version: 5.6.28-0ubuntu0.14.04.1 (Ubuntu) 修改配置文件 /etc/ ...

  10. C#计算代码行数

    class Program { static void Main(string[] args) { int totalLineCount = 0; string directory; if(args. ...