「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
描述
哦,不!你不小心把一个长篇文章中的空格、标点都删掉了,并且大写也弄成了小写。像句子"I reset the computer. It still didn’t boot!"已经变成了"iresetthecomputeritstilldidntboot"。在处理标点符号和大小写之前,你得先把它断成词语。当然了,你有一本厚厚的词典dictionary,不过,有些词没在词典里。假设文章用sentence表示,设计一个算法,把文章断开,要求未识别的字符最少,返回未识别的字符数。
注意:本题相对原题稍作改动,只需返回未识别的字符数
- 示例 1:
输入:
dictionary = ["looked","just","like","her","brother"]
sentence = "jesslookedjustliketimherbrother"
输出: 7
解释: 断句后为"jess looked just like tim her brother",共7个未识别字符。
- 提示:
- 0 <= len(sentence) <= 1000
- dictionary中总字符数不超过 150000。
- 你可以认为dictionary和sentence中只包含小写字母。
解析
本题相对比较容易理解,这里直接上解法:
- 核心的转移函数,v[x] = min(v[x - w1.length], v[x - w2.length], ..., v[x-1] + 1)
- 外循环:字符串逐位处理,表示以当前位置结束时的句子,计算最小未识别的字符数
- 内循环:词典遍历,表示如果最后满足该单词时的最小未识别的字符数
- 内循环完成后,就完成一次转移函数
class Solution {
public int respace(String[] dictionary, String sentence) {
if (sentence == null || sentence.isEmpty()) {
return 0;
}
int length = sentence.length();
int[] unknowns = new int[length];
for (int end = 1; end <= length; end++) {
// 初始化值
if (end - 2 >= 0) {
unknowns[end - 1] = unknowns[end - 2] + 1;
} else {
unknowns[end - 1] = 1;
}
// 更新
for (String word : dictionary) {
int start = end - word.length();
if (start < 0) {
continue;
}
String current = sentence.substring(start, end);
if (current.equals(word)) {
if (start > 0) {
if (unknowns[start - 1] < unknowns[end - 1]) {
unknowns[end - 1] = unknowns[start - 1];
}
} else {
unknowns[end - 1] = 0;
}
}
}
}
return unknowns[length - 1];
}
}
运行结果:
执行结果:通过
执行用时:74 ms, 在所有 Java 提交中击败了42.81%的用户
内存消耗:38.5 MB, 在所有 Java 提交中击败了95.32%的用户