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. Python(五)模块

    本章内容: 模块介绍 time & datetime random os sys json & picle hashlib XML requests ConfigParser logg ...

  2. CSS教程:div垂直居中的N种方法以及多行文本垂直居中的方法

    在说到这个问题的时候,也许有人会问CSS中不是有vertical-align属性来设置垂直居中的吗?即使是某些浏览器不支持我只需做少许的CSS Hack技术就可以啊!所以在这里我还要啰嗦两句,CSS中 ...

  3. JS魔法堂:不完全国际化&本地化手册 之 实战篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

  4. 数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇

    <数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇>一文让读者了解了 HT的 2D 拓扑图组件使用,本文将对 HT 的 3D 功能做个综合性的介绍,以便初学者可快速上手使用 HT ...

  5. GridView中显示时间日期格式问题

    以下都是GridView基本常用的日期,时间格式 形式 语法 结果 注释 数字 {0:N2} 12.36   数字 {0:N0} 13   货币 {0:c2} $12.36   货币 {0:c4} $ ...

  6. django+mysql学习笔记

    这段时间在学习mysql+django的知识点.借此记录以下学习过程遇到的坑以及心得. 使用的工具是navicat for mysql python 2.7.12 mysql-python 1.2.3 ...

  7. Elastic学习第一天遇到的问题以及添加的一些操作

    1.刚开始安装好了之后,启动之后, 报错: ERROR: max file descriptors [] ] 需要设置max file descriptors为65536,出现这个是因为普通的用户是1 ...

  8. apache.commons.io.IOUtils: 一个很方便的IO工具库(比如InputStream转String)

    转换InputStream到String, 比如 //引入apache的io包 import org.apache.commons.io.IOUtils; ... ...String str = IO ...

  9. CentOS7下安装Python的pip

    root用户使用yum install -y python-pip 时会报如下错误: No package python-pip available Error:Nothing to do 解决方法如 ...

  10. CentOS7中安装Python3.5

    1.下载 https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz 2.上传到服务器 3. 安装相关依赖 yum install gcc ope ...