题目难度: 中等
今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~
哦,不!你不小心把一个长篇文章中的空格、标点都删掉了,并且大写也弄成了小写。像句子"I reset the computer. It still didn’t boot!“已经变成了"iresetthecomputeritstilldidntboot”。在处理标点符号和大小写之前,你得先把它断成词语。当然了,你有一本厚厚的词典 dictionary,不过,有些词没在词典里。假设文章用 sentence 表示,设计一个算法,把文章断开,要求未识别的字符最少,返回未识别的字符数。
注意:本题相对原题稍作改动,只需返回未识别的字符数
O(N^2*M): 假设 N 是 sentence 长度, M 是字典中的字符串的平均长度, 需要两层遍历找最小 dp 值 (O(N^2)), 而查找字符串的复杂度是 O(M)O(N+C): 假设 N 是 sentence 长度, C 是字典中的总字符数, 记忆化搜索的缓存空间是 O(N), 将字典列表转成字符串集合的空间是 O©class Solution:
def respace(self, dictionary: List[str], sentence: str) -> int:
# 动态规划+字符串集合
# 先将给定的字典列表转成集合, 降低查找的时间复杂度
dictionary = set(dictionary)
n = len(sentence)
# 初始化未识别字符数为最大值
dp = [n] * (n + 1)
# 空字符串时未识别字符数为0
dp[n] = 0
for i in range(n)[::-1]:
# 逆序求dp值
for j in range(i + 1, n + 1):
# 如果sentence[i:j]在字典中, 则可以直接使用它, 此时未识别字符数是0, 否则就是对应的长度
unidentified = 0 if sentence[i:j] in dictionary else j - i
# 找最小的dp值
dp[i] = min(dp[i], dp[j] + unidentified)
return dp[0]
大家可以在下面这些地方找到我~😊
我的公众号: 算法精选, 欢迎大家扫码关注~😊
