题目难度: 中等
原题链接[1]
今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~
给定一个较长字符串 big 和一个包含较短字符串的数组 smalls,设计一个方法,根据 smalls 中的每一个较短字符串,对 big 进行搜索。输出 smalls 中的字符串在 big 里出现的所有位置 positions,其中 positions[i]为 smalls[i]出现的所有位置。
class Solution: def multiSearch(self, big: str, smalls: List[str]) -> List[List[int]]: # 方法1: 语言自带find res = [] for s in smalls: res.append([]) # 初始化起点为-1, 因为下面的find逻辑是从i+1开始查找 i = -1 if s != "": while True: # i是上一个查找到的起点, 接下来从i+1开始查, 保证不重复 i = big.find(s, i + 1) if i != -1: # 找到了, 追加起点 res[-1].append(i) else: # 没找到, 跳出循环 break return resclass Solution: def multiSearch(self, big: str, smalls: List[str]) -> List[List[int]]: # 方法2: 逆向思考+trie存small+遍历big起点 class Node: def __init__(self, c): self.c = c # children字典, 存储字符到节点的映射 self.children = {} # small字符串下标, 初始化为-1, 只有当遍历到small最后一个字符时才赋值, 保证完整性 self.index = -1 n, m = len(big), len(smalls) root = Node("") for i, w in enumerate(smalls): # 将当前字符串加入trie中, 达到终点时记录当前下标 # 因为smalls的字符串都不重复, 所以不存在下标覆盖的情况 cur = root for c in w: if c not in cur.children: cur.children[c] = Node(c) cur = cur.children[c] # 赋值下标, 从root到cur的路径形成了完整的当前small字符串 cur.index = i # 预生成结果列表 res = [[] for _ in range(m)] for start in range(n): # 遍历big的每个起点start cur = root i = start while cur and i < n: c = big[i] if c not in cur.children: # 当前字符不在trie中, 后面就更不存在有效的small字符串了, 直接退出循环 break # 进入下一层 cur = cur.children[c] i += 1 if cur.index != -1: # 当前节点索引不是-1, 说明找到了一个完整的small字符串 (从root一路到cur) # 此时需要将结果列表的small下标处追加上当前big的起点start, 表示这个small字符串在start位置处出现 res[cur.index].append(start) return res[1]
原题链接: https://leetcode.cn/problems/multi-search-lcci/
| 留言与评论(共有 0 条评论) “” |