【每日一题】LeetCode. 面试题17.13. 恢复空格

每日一题,防止痴呆 = =

一、题目大意

哦,不!你不小心把一个长篇文章中的空格、标点都删掉了,并且大写也弄成了小写。像句子"I reset the computer. It still didn’t boot!“已经变成了"iresetthecomputeritstilldidntboot”。在处理标点符号和大小写之前,你得先把它断成词语。当然了,你有一本厚厚的词典dictionary,不过,有些词没在词典里。假设文章用sentence表示,设计一个算法,把文章断开,要求未识别的字符最少,返回未识别的字符数。

注意:本题相对原题稍作改动,只需返回未识别的字符数
【每日一题】LeetCode. 面试题17.13. 恢复空格_第1张图片
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/re-space-lcci

二、题目思路以及AC代码

思路

这道题一开始的思路就是动态规划,然后大约估计了一下复杂度,是O(N^2),因为看到题目给定的字符串长度是1000,所以我觉得方法应该没有什么问题了。

我们设 dp[i] 表示字符串第 i 个字符之前,可识别的最多的字符数量是多少,这样的话,我们的结果其实就是 len - dp[len]。当我们要求 dp[i] 时,我们只需要让 j 遍历 0 ~ i-1,首先看由 [j, i-1]这个子串是否在字典中,如果在的话,那么dp[i] = max(dp[i], dp[j] + i - j),如果不在,那么dp[i] = max(dp[i], dp[j])。这样,我们理论上就可以求得最终得结果了。

我以为这个思路是考点,没想到,考点还在下面,我直接按照思路实现了代码,发现超时了?明明就是O(N^2)的算法,怎么会超时呢?我有以下两个想法。

  • 首先,我这里判断子串是否在字典中使用的是 unordered_map,通过以往的做题经历,unordered_map的速度是比较慢的,会比 unordered_set慢一些,所以可能换成unordered_set会好一些。
  • 其次,我发现在两重循环里面,我还用到了string里面的substr方法,这个过程肯定是很慢的,如果可以的话,需要找方法来优化。

当时首先从简单的开始了,我尝试把 unordered_map 换成 unordered_set,果然,AC了,只不过时间花费还是有点长,然后只能考虑第二种优化方法了。

其实第二种优化方法我是看的题解,因为写完一遍代码实在不想再来一遍了 = =,比较懒。主要有两种方法吧,但其实都是利用了如果我已知字符串 s 在集合 S 中,那么我就可以在O(1)的复杂度内,判断 s 加上一个字符是否在集合 S 中。

  • 字典树
  • 字符串哈希

这两种方法详细的还是找一些别的教程吧,这里就不展开了。

AC代码

这里只有我那么贼慢AC的代码,关于字典树和字符串哈希的代码,因为比较懒,就算了 = =,有需要的可以去LeetCode官解里面看。

class Solution {
public:
    int respace(vector<string>& dictionary, string sentence) {
        unordered_set<string> mm;
        int s_len = sentence.length();

        for (auto dict: dictionary) {
            mm.insert(dict);
        }

        int dp[s_len + 1];
        for (int i=0;i<=s_len;i++) {
            dp[i] = 0;
        }

        for (int i=1;i<=s_len;i++) {
            for (int j=0;j<i;j++) {
                if (mm.find(sentence.substr(j, i - j)) != mm.end())
                    dp[i] = max(dp[i], dp[j] + i - j);
                else 
                    dp[i] = max(dp[i], dp[j]);
            }
        }

        return s_len - dp[s_len];
    }
};

如果有问题,欢迎大家指正!!!

你可能感兴趣的:(每日一题,算法,leetcode,动态规划,哈希表,字符串)