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. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    RAC 工作原理和相关组件(三) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  2. Vertica集群单节点宕机恢复方法

    Vertica集群单节点宕机恢复方法 第一种方法: 直接通过admintools -> 5 Restart Vertica on Host 第二种方法: 若第一种方法无法恢复,则清空宕机节点的c ...

  3. Solr Facet 默认值

    前言 今天在用Solr Facet遇到了默认值的问题,我用Facet.field查询发现数据总共100条,刚开始没有注意,发现少个别数据,但是用这几个个别的id查询又能查出来数据.才发现是Facet默 ...

  4. 【分布式】Zookeeper与Paxos

    一.前言 在学习了Paxos在Chubby中的应用后,接下来学习Paxos在开源软件Zookeeper中的应用. 二.Zookeeper Zookeeper是一个开源的分布式协调服务,其设计目标是将那 ...

  5. 6.C#WinForm基础城市选择器

    源码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data ...

  6. ASP.NET Core 中文文档 第三章 原理(14)服务器

    原文:Servers 作者:Steve Smith 翻译:谢炀(Kiler) 校对:许登洋(Seay).姚阿勇(Dr.Yao) ASP.NET Core 已完全从承载应用程序的 Web 服务器环境中分 ...

  7. 最适合作为Java基础面试题之Singleton模式

    看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...

  8. shell脚本规划化模板

    shell脚本规划化模板 Linux运维过程中,shell脚本是不可缺少的工具,但是每个运维人员编程的习惯都不一样,很多时候就是实现某个功能,写出来的脚本都是烂七八糟的.脚本必须规范化,应该从以后几个 ...

  9. 『.NET Core CLI工具文档』(七)dotnet-new

    说明:本文是个人翻译文章,由于个人水平有限,有不对的地方请大家帮忙更正. 原文:dotnet-new 翻译:dotnet-new 名称 dotnet-new -- 创建一个新的 .NET Core 项 ...

  10. WebUtils-网络请求工具类

    网络请求工具类,大幅代码借鉴aplipay. using System; using System.Collections.Generic; using System.IO; using System ...