0472. 连接词
题目地址(472. 连接词)
https://leetcode-cn.com/problems/concatenated-words/
题目描述
前置知识
公司
阿里
字节
思路
本题我的思路是直接使用前缀树来解决。标准的前缀树模板我在之前的题解中提到了,感兴趣的可以到下方的相关题目中查看。
这道题这里我们不需要 search,我们的做法是:
先进行一次遍历,将 words 全部插入(insert)到前缀树中。
然后再进行一次遍历,查找每一个单词有几个单词表中的单词组成
如果大于 2,则将其加入到 res 中
最后返回 res 即可
我们构造的前缀树大概是这样的:
问题的关键在于第二步中的查找每一个单词有几个单词表中的单词组成。 其实如果你了解前缀树的话应该不难写出来。 比如查找 catsdogcats:
我们先从 c 到 a 到 t,发现 t 是单词结尾,我们数量 + 1
然后将剩下的部分“sdogcats”重新执行上述过程。
s 发现找不到,我们返回 0
因此最终结果是 1
很明显这个逻辑是错误的,正确的划分应该是:
我们先从 c 到 a 到 t,再到 s,此时数量 + 1
然后将剩下的“dogcats”重复上述过程
dog 找到了,数量 + 1
最后将 cats 加入。也找到了,数量再加 1
由于我们并不知道 cat 这里断开,结果更大?还是 cats 这里断开结果更大?因此我们的做法是将其全部递归求出,然后取出最大值即可。如果我们直接这样递归的话,可能会超时,卡在最后一个测试用例上。一个简单的方式是记忆化递归,从而避免重复计算,经测试这种方法能够通过。
2021-12-28 updated: 由于力扣增加了测试用例,导致了上面的仅仅依靠记忆化也是无法 AC 的。需要进一步优化。
我们可以将 words 排序,这样就可以剪枝了。如何剪枝呢?直接用代码比较直观:
如果如果 word 是合成词,那么没有必要将其加到 trie 中,因为这不影响答案,最多就是 cntWords 算出来的数字不对了。不过这道题对具体的数字不感兴趣,我们只关心是否大于 2。
需要注意的是, 一定要排序。 否则如果合成词在前就没有优化效果了,达不到剪枝的目的。
关键点分析
前缀树
记忆化搜索
排序后 word 选择性插入到 trie 中
代码
代码支持:Python3
Python3 Code:
相关题目
最后更新于