[英雄星球六月集训LeetCode解题日报] 第23日 字典树
2022/6/29 4:20:18
本文主要是介绍[英雄星球六月集训LeetCode解题日报] 第23日 字典树,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
日报
- 今天两题代码可以复用,直接字典树模板套进来,写个查询即可。
题目
一、 472. 连接词
链接: 472. 连接词
1. 题目描述
- 连接词
难度:困难
给你一个 不含重复 单词的字符串数组 words
,请你找出并返回 words
中的所有 连接词 。
连接词 定义为:一个完全由给定数组中的至少两个较短单词组成的字符串。
示例 1:
输入:words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] 输出:["catsdogcats","dogcatsdog","ratcatdogcat"] 解释:"catsdogcats" 由 "cats", "dog" 和 "cats" 组成; "dogcatsdog" 由 "dog", "cats" 和 "dog" 组成; "ratcatdogcat" 由 "rat", "cat", "dog" 和 "cat" 组成。
示例 2:
输入:words = ["cat","dog","catdog"] 输出:["catdog"]
提示:
1 <= words.length <= 104
0 <= words[i].length <= 30
words[i]
仅由小写字母组成0 <= sum(words[i].length) <= 105
2. 思路分析
- 先过一遍·
words
建立字典树。 - 接下来我们定义一个查询方法:
find_split_count(s)
,这个方法的作用是用words中的单词恰好
拼接s,寻找最多能把word切几段。 - 那么答案显然就是
words
中每个单词执行一遍这个函数,返回值>=2的单词就是答案。 - 当我们用字典树的查找方法,从s头开始匹配,寻找到一个完整单词时,从这里把s切成两半s1,s2.
- 显然s1在
words
中出现了,那么只要s2也在words
中出现,那么这个s就是满足题意的字符串;s2也可本身不用出现,只需要它能用words
中多个字符串拼起来即可。 - 显然s2可以递归这个函数本身
find_split_count(s2)
。 - 右半部分返回值r>=1,加上左半部分本身是一个合法串,l=1,那么这个串已经满足题意,可以提前返回了。
- 具体实现时,为了不疯狂切片,我们方法声明为find_split_count(s,start,n),start和n代表s从下标start开始匹配到n结束。
- 一定注意最后返回时要判断cur.is_end,如果非结束,那说明匹配失败,返回0。
3. 代码实现
class TrieNode: def __init__(self,cnt=0): self.cnt = cnt self.next = [None]*26 self.is_end = False def insert(self, word: str) -> None: cur = self for c in word: i = ord(c)-ord('a') if not cur.next[i] : # 没有这个字符 cur.next[i] = TrieNode() cur = cur.next[i] cur.cnt += 1 cur.is_end = True def find_split_count(self,word,start,n): if start == n: return 0 cur = self m = 0 for i in range(start,n): c = word[i] idx = ord(c) - ord('a') if not cur.next[idx]: return 0 cur = cur.next[idx] if cur.is_end: m = self.find_split_count(word,i+1,n)+1 if m >= 2: return m return m if cur.is_end else 0 class Solution: def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]: trie = TrieNode() n = len(words) for word in words: trie.insert(word) # word='nuqhmfj' # print(trie.find_split_count(word,0,len(word))) return [word for word in words if trie.find_split_count(word,0,len(word)) >=2]
二、 面试题 17.15. 最长单词
链接: 面试题 17.15. 最长单词
1. 题目描述
面试题 17.15. 最长单词
难度:中等
给定一组单词words
,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成。若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串。
示例:
输入: ["cat","banana","dog","nana","walk","walker","dogwalker"] 输出: "dogwalker" 解释: "dogwalker"可由"dog"和"walker"组成。
提示:
0 <= len(words) <= 200
1 <= len(words[i]) <= 100
2. 思路分析
- 这题和上题字典树部分代码完全一致。
- 满足条件的单词判断一下长度和字典序即可。
3. 代码实现
class TrieNode: def __init__(self, cnt=0): self.cnt = cnt self.next = [None] * 26 self.is_end = False def insert(self, word: str) -> None: cur = self for c in word: i = ord(c) - ord('a') if not cur.next[i]: # 没有这个字符 cur.next[i] = TrieNode() cur = cur.next[i] cur.cnt += 1 cur.is_end = True def find_split_count(self, word, start, n): if start == n: return 0 cur = self m = 0 for i in range(start, n): idx = ord(word[i]) - ord('a') if not cur.next[idx]: return 0 cur = cur.next[idx] if cur.is_end: m = self.find_split_count(word, i + 1, n) + 1 if m >= 2: # print(word[start:i + 1], word[i + 1:], m) return m return m if cur.is_end else 0 class Solution: def longestWord(self, words: List[str]) -> str: ans = '' m = 0 trie = TrieNode() for word in words: trie.insert(word) for word in words: n = len(word) if trie.find_split_count(word,0,n)>=2: if n > m : m = n ans = word elif n == m and word < ans: ans = word return ans
人生苦短,我用Python!
这篇关于[英雄星球六月集训LeetCode解题日报] 第23日 字典树的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27Excel中实现拖动排序的简单教程
- 2024-11-27Rocket消息队列资料:新手入门指南
- 2024-11-27rocket消息队资料详解与入门指南
- 2024-11-27RocketMQ底层原理资料详解入门教程
- 2024-11-27RocketMQ项目开发资料:新手入门教程
- 2024-11-27RocketMQ项目开发资料详解
- 2024-11-27RocketMQ消息中间件资料入门教程
- 2024-11-27初学者指南:深入了解RocketMQ源码资料
- 2024-11-27Rocket消息队列学习入门指南
- 2024-11-26Rocket消息中间件教程:新手入门详解