面试题 17.13. 恢复空格
思路:
先看错误答案:
public int respace(String[] dictionary, String sentence) {
int[] dp = new int[sentence.length()+1];
for(int i=0;i<=sentence.length();i++) dp[i] = i;
for(int i=1;i<=sentence.length();++i){
for(String word:dictionary){
if(word.length()<=i){
if(word.equals(sentence.substring(i-word.length(),i)))
dp[i]=Math.min(dp[i-1]+1,Math.min(dp[i],dp[i-word.length()]));
}
}
}
return dp[sentence.length()];
}
很常见的动态规划,但是测试用例的输出结果总是比实际大,仔细看会发现中间的两层if循环是有问题的,因为一旦这两个if其中有一个的结果不为true,动态数组将不被更新,这就是问题所在,所以我们应该加个else,不过如果加else可能要加两个,不如最后做个统一处理:
public int respace(String[] dictionary, String sentence) {
int[] dp = new int[sentence.length()+1];
for(int i=0;i<=sentence.length();i++) dp[i] = i;
for(int i=1;i<=sentence.length();++i){
for(String word:dictionary){
if(word.length()<=i){
if(word.equals(sentence.substring(i-word.length(),i)))
dp[i]=Math.min(dp[i],dp[i-word.length()]);
}
dp[i] = Math.min(dp[i],dp[i-1]+1);
}
}
return dp[sentence.length()];
}
这个处理器是也可以放在前面,也就是第一层循环下(因为这里必须会执行),这时候甚至可以代替初始化,因此不用再初始化了(但是dp[0] = 0是需要的):
public int respace(String[] dictionary, String sentence) {
int[] dp = new int[sentence.length()+1];
//for(int i=0;i<=sentence.length();i++) dp[i] = i;
for(int i=1;i<=sentence.length();++i){
dp[i] = dp[i - 1] + 1; //如果sentence有的单词如果识别不了的话 那dp数组就不会更新
for(String word:dictionary){
if(word.length()<=i){
if(word.equals(sentence.substring(i-word.length(),i)))
dp[i]=Math.min(dp[i-1]+1,Math.min(dp[i],dp[i-word.length()]));
}
}
}
return dp[sentence.length()];
}
还有一种方法就是使用前缀树,下次更新。。。