力扣:17.13. 恢复空格

131 阅读2分钟

「这是我参与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中只包含小写字母。

解析

本题相对比较容易理解,这里直接上解法:

  1. 核心的转移函数,v[x] = min(v[x - w1.length], v[x - w2.length], ..., v[x-1] + 1)
  2. 外循环:字符串逐位处理,表示以当前位置结束时的句子,计算最小未识别的字符数
  3. 内循环:词典遍历,表示如果最后满足该单词时的最小未识别的字符数
  4. 内循环完成后,就完成一次转移函数
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%的用户