题目:恢复空格
哦,不!你不小心把一个长篇文章中的空格、标点都删掉了,并且大写也弄成了小写。
像句子"I reset the computer. It still didn’t boot!"已经变成了
"iresetthecomputeritstilldidntboot"。
在处理标点符号和大小写之前,你得先把它断成词语。
当然了,你有一本厚厚的词典dictionary,不过,有些词没在词典里。
假设文章用sentence表示,设计一个算法,把文章断开,
要求未识别的字符最少,返回未识别的字符数。
注意:本题相对原题稍作改动,只需返回未识别的字符数
输入:
dictionary = ["looked","just","like","her","brother"]
sentence = "jesslookedjustliketimherbrother"
输出: 7
解释: 断句后为"jess looked just like tim her brother",共7个未识别字符。
思路
定义 dp[i] 表示考虑前 ii 个字符最少的未识别的字符数量,从前往后计算 dp 值。
考虑转移方程,每次转移的时候我们考虑第j(j≤i) 个到第 i 个字符组成的子串sentence[j−1⋯i−1] (注意字符串下标从 00 开始)是否能在词典中找到,如果能找到的话按照定义转移方程即为
dp[i]=min(dp[i],dp[j−1])
否则没有找到的话我们可以复用 [i-1]dp[i−1] 的状态再加上当前未被识别的第 ii 个字符,因此此时 dp 值为
dp[i]=dp[i−1]+1
解法:字符串哈希
class Solution {
static final long P = Integer.MAX_VALUE;
static final long BASE = 41;
public int respace(String[] dictionary, String sentence) {
Set<Long> hashValues = new HashSet<Long>();
for (String word : dictionary) {
hashValues.add(getHash(word));
}
int[] f = new int[sentence.length() + 1];
Arrays.fill(f, sentence.length());
f[0] = 0;
for (int i = 1; i <= sentence.length(); ++i) {
f[i] = f[i - 1] + 1;
long hashValue = 0;
for (int j = i; j >= 1; --j) {
int t = sentence.charAt(j - 1) - 'a' + 1;
hashValue = (hashValue * BASE + t) % P;
if (hashValues.contains(hashValue)) {
f[i] = Math.min(f[i], f[j - 1]);
}
}
}
return f[sentence.length()];
}
public long getHash(String s) {
long hashValue = 0;
for (int i = s.length() - 1; i >= 0; --i) {
hashValue = (hashValue * BASE + s.charAt(i) - 'a' + 1) % P;
}
return hashValue;
}
}
Comments | 0 条评论