zoukankan      html  css  js  c++  java
  • [面试题 17.13. 恢复空格]

    [面试题 17.13. 恢复空格]

    哦,不!你不小心把一个长篇文章中的空格、标点都删掉了,并且大写也弄成了小写。像句子"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个未识别字符。
    

    提示:

    • 0 <= len(sentence) <= 1000
    • dictionary中总字符数不超过 150000。
    • 你可以认为dictionarysentence中只包含小写字母。

    思路:动态规划:令 dp[i]表示前i个字符中未能识别的最少字符个数,我们从第i个字符开始向查找字符串是否存在dectionary[]

    不存在:dp[i] = Min(dp[i-1]+1,dp[i])

    存在:dp[i] = Min(dp[i], dp[i-len])

    比较查找字符串的过程可以用优化:

    比如存在字典 :mimy, why ,当我们从后往前找到 ty时就不必再往前找了,因为字典中没有以 ty结尾的词,该思路可以用字典树是实现

    不过增加了空间复杂度

    public int respace(String[] dictionary, String sentence) {
            int n = sentence.length();
            Trie root = new Trie();
            for (String word: dictionary) {
                root.insert(word);
            }
    
            int[] dp = new int[n + 1];
            Arrays.fill(dp, Integer.MAX_VALUE);
            dp[0] = 0;
            for (int i = 1; i <= n; ++i) {
                dp[i] = dp[i - 1] + 1;
    
                Trie curPos = root;
                for (int j = i; j >= 1; --j) {
                    int t = sentence.charAt(j - 1) - 'a';
                    if (curPos.next[t] == null) {
                        break;
                    } else if (curPos.next[t].isEnd) {
                        dp[i] = Math.min(dp[i], dp[j - 1]);
                    }
                    if (dp[i] == 0) {
                        break;
                    }
                    curPos = curPos.next[t];
                }
            }
            return dp[n];
        }
    }
    
    class Trie {
        public Trie[] next;
        public boolean isEnd;
    
        public Trie() {
            next = new Trie[26];
            isEnd = false;
        }
    
        public void insert(String s) {
            Trie curPos = this;
    
            for (int i = s.length() - 1; i >= 0; --i) {
                int t = s.charAt(i) - 'a';
                if (curPos.next[t] == null) {
                    curPos.next[t] = new Trie();
                }
                curPos = curPos.next[t];
            }
            curPos.isEnd = true;
        }
    
    因为我喜欢追寻过程中的自己
  • 相关阅读:
    利用node搭建本地服务器调试代码
    WCF与WebService的区别
    图解HTTPS
    XMAL语法系列之-(2)---WPF控件继承图
    俩种分页的实现!
    设置二级域名共享一级域名Cookie和删除共享Cookie
    Jquery 操作IFrame
    sql中的常见的全局变量
    sql字段中逗号分隔字符串的判断
    sql sever 字符串函数
  • 原文地址:https://www.cnblogs.com/IzuruKamuku/p/14359754.html
Copyright © 2011-2022 走看看