C++实现LeetCode(140.拆分词句之二)

这篇文章主要介绍了C++实现LeetCode(140.拆分词句之二),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

C++实现LeetCode(140.拆分词句之二),久久派带你了解更多相关信息。

[LeetCode] 140.Word Break II 拆分词句之二

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

Note:

  • The same word in the dictionary may be reused multiple times in the segmentation.
  • You may assume the dictionary does not contain duplicate words.

Example 1:

Input: s = \”catsanddog\” wordDict = [\”cat\”, \”cats\”, \”and\”, \”sand\”, \”dog\”] Output: [   \”cats and dog\”,   \”cat sand dog\” ]

Example 2:

Input:
s = \”pineapplepenapple\”
wordDict = [\”apple\”, \”pen\”, \”applepen\”, \”pine\”, \”pineapple\”]
Output:
[
\”pine apple pen apple\”,
\”pineapple pen apple\”,
\”pine applepen apple\”
]
Explanation: Note that you are allowed to reuse a dictionary word.

Example 3:

Input:
s = \”catsandog\”
wordDict = [\”cats\”, \”dog\”, \”sand\”, \”and\”, \”cat\”]
Output:
[]

这道题是之前那道Word Break 拆分词句的拓展,那道题只让我们判断给定的字符串能否被拆分成字典中的词,而这道题加大了难度,让我们求出所有可以拆分成的情况,就像题目中给的例子所示。之前的版本中字典wordDict的数据类型是HashSet,现在的不知为何改成了数组vector,而且博主看到第二个例子就笑了,PPAP么,哈哈~

根据老夫行走江湖多年的经验,像这种返回结果要列举所有情况的题,十有八九都是要用递归来做的。当我们一时半会没有啥思路的时候,先不要考虑代码如何实现,如果就给你一个s和wordDict,不看Output的内容,你会怎么找出结果。比如对于例子1,博主可能会先扫一遍wordDict数组,看有没有单词可以当s的开头,那么我们可以发现cat和cats都可以,比如我们先选了cat,那么此时s就变成了 \”sanddog\”,我们再在数组里找单词,发现了sand可以,最后剩一个dog,也在数组中,于是一个结果就出来了。然后回到开头选cats的话,那么此时s就变成了 \”anddog\”,我们再在数组里找单词,发现了and可以,最后剩一个dog,也在数组中,于是另一个结果也就出来了。那么这个查询的方法很适合用递归来实现,因为s改变后,查询的机制并不变,很适合调用递归函数。再者,我们要明确的是,如果不用记忆数组做减少重复计算的优化,那么递归方法跟brute force没什么区别,大概率无法通过OJ。所以我们要避免重复计算,如何避免呢,还是看上面的分析,如果当s变成 \”sanddog\”的时候,那么此时我们知道其可以拆分成sand和dog,当某个时候如果我们又遇到了这个 \”sanddog\”的时候,我们难道还需要再调用递归算一遍吗,当然不希望啦,所以我们要将这个中间结果保存起来,由于我们必须要同时保存s和其所有的拆分的字符串,那么可以使用一个HashMap,来建立二者之间的映射,那么在递归函数中,我们首先检测当前s是否已经有映射,有的话直接返回即可,如果s为空了,我们如何处理呢,题目中说了给定的s不会为空,但是我们递归函数处理时s是会变空的,这时候我们是直接返回空集吗,这里有个小trick,我们其实放一个空字符串返回,为啥要这么做呢?我们观察题目中的Output,发现单词之间是有空格,而最后一个单词后面没有空格,所以这个空字符串就起到了标记当前单词是最后一个,那么我们就不要再加空格了。接着往下看,我们遍历wordDict数组,如果某个单词是s字符串中的开头单词的话,我们对后面部分调用递归函数,将结果保存到rem中,然后遍历里面的所有字符串,和当前的单词拼接起来,这里就用到了我们前面说的trick。for循环结束后,记得返回结果res之前建立其和s之间的映射,方便下次使用,参见代码如下:

解法一:

class Solution {public:    vector<string> wordBreak(string s, vector<string>& wordDict) {        unordered_map<string, vector<string>> m;        return helper(s, wordDict, m);    }    vector<string> helper(string s, vector<string>& wordDict, unordered_map<string, vector<string>>& m) {        if (m.count(s)) return m[s];        if (s.empty()) return {\"\"};        vector<string> res;        for (string word : wordDict) {            if (s.substr(0, word.size()) != word) continue;            vector<string> rem = helper(s.substr(word.size()), wordDict, m);            for (string str : rem) {                res.push_back(word + (str.empty() ? \"\" : \" \") + str);            }        }        return m[s] = res;    }};

我们也可以将将主函数本身当作递归函数,这样就不用单独的使用一个递归函数了,不过我们的HashMap必须是全局了,写在外部就好了,参见代码如下:

解法二:

class Solution {public:    unordered_map<string, vector<string>> m;    vector<string> wordBreak(string s, vector<string>& wordDict) {        if (m.count(s)) return m[s];        if (s.empty()) return {\"\"};        vector<string> res;        for (string word : wordDict) {            if (s.substr(0, word.size()) != word) continue;            vector<string> rem = wordBreak(s.substr(word.size()), wordDict);            for (string str : rem) {                res.push_back(word + (str.empty() ? \"\" : \" \") + str);            }        }        return m[s] = res;    }};

类似题目:

Word Break

Concatenated Words

参考资料:

****/d/file/p/2021072818002478409/2021072818002478410

****/d/file/p/2021072818002478415/2021072818002478416

****/d/file/p/2021072818002478421/2021072818002478422

到此这篇关于C++实现LeetCode(140.拆分词句之二)的文章就介绍到这了,更多相关C++实现拆分词句之二内容请搜索趣讯吧以前的文章或继续浏览下面的相关文章希望大家以后多多支持趣讯吧!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/7260.html

(0)
nan
上一篇 2021-07-29
下一篇 2021-07-29

相关推荐

  • 旅客被新加坡柜员辱骂是狗 南航通报:停止该名人员服务资格 !

    5月27日下午,有媒体报道称,旅客袁先生称其在新加坡机场南航柜台值机时,被告知调换至安全通道需额外收费,用中文提出质疑后被柜台人员冷漠对待,还被辱骂“是狗”。27日晚间,“中国南方航空驻新加坡营业部”微信公众号发布情况说明:5月23日,我们收到旅客在新加坡乘机遭遇柜台服务人员辱骂的投诉后,及时启动调

    热点头条 2023-05-28
    0
  • 变压器的原理和作用(变压器转变电压的工作原理)

    摘要:变压器的工作原理,下图是变压器的结构示意图,图中,左侧是一次绕组,右侧是二次绕组,一次和二次绕组均绕在铁芯上。变压器只能输入交流电压。从变压器一次绕组两端输入交流电压,从二次绕组输出交流电压。

    2023-05-12
    0
  • 给河南的捐款用到哪儿了?最新明细公示

    作为河南省接受外界爱心捐助的重要机构,河南此次水灾发生以来,爱心捐款源源不断汇集到河南省慈善总会。截止7月23日20时,河南省慈善总会已收到抗洪救灾捐款26.64亿元,已拨付17.98亿元。

    2021-07-24 热点头条
    0
  • 如何重置电脑(如何重置win10系统)

    如何重置电脑(如何重置win10系统)点击【开始】-【设置】-【更新和安全】;选择【恢复】,在重置此电脑下面,点击【开始】;根据实际情况选择【保留我的文件】或【删除所有内容】;点击【下一步】并确认【重置】,等待电脑初始化完成即可。以下是详细

    2021-11-28
    0
  • word转pdf工具类(免费的word转换器推荐)

    Word文档怎么转换成PDF?有的时候会遇到Word转格式的问题,但是缺少经验的我们总是不知道如何实现,直接修改文档的后缀名肯定是不可以的,会影响整个文档的排版,可能还会出现乱码的情况。那么我们应该用什么样的方法进行转换呢?下面小编就给大家简单介绍一

    2022-01-13 热点头条
    0
  • 南京今日确诊人数(当地大约多久解除疫情)

    最近,江苏南京爆发新一轮新冠阳性疫情之后,因为外溢的原因,导致多地也确诊相关本土病例。南京此轮疫情已经持续几天了,那么,南京今日确诊人数是多少呢?还有当地大约多久解除疫情

    热点头条 2021-07-26
    0

发表回复

登录后才能评论