• 【Leetcode】758. Bold Words in String


    题目地址:

    https://leetcode.com/problems/bold-words-in-string/description/

    给定一个长 n n n的字符串 s s s和一个单词列表 A A A,单词列表里的词都需要做加粗记号。求加上加粗记号的最终字符串。加粗记号指的是在 s s s的加粗的部分两边加上""""。注意,对于加粗记号,必须保证这个记号是包括了最长的一段,且不要嵌套,即加粗记号的紧邻的左右两边的字符必定不加粗。题目保证所有出现的字符只有英文字母和数字。题目保证 A A A中字符串的长度范围是 [ 1 , 10 ] [1, 10] [1,10]

    正解是AC自动机,参考https://blog.csdn.net/qq_46105170/article/details/128060295。也可以用字符串哈希来做。先求出 A A A中所有字符串的哈希值,并且记录一下 A A A中最短和最长的字符串长度,再求 s s s的哈希数组。接着枚举 s [ i ] s[i] s[i],看以 s [ i ] s[i] s[i]结尾是否能取到 A A A中的字符串,可以直接枚举长度,并且长度从大到小枚举(如果长度大的已经覆盖了,小的就不用继续枚举了)。匹配的过程可以直接比较哈希值。代码如下:

    class Solution {
     public:
      using UL = unsigned long;
      string boldWords(vector<string>& ws, string s) {
        UL P = 131;
        int n = s.size();
        vector<UL> ha(n + 1), pow(n + 1);
        pow[0] = 1;
        for (int i = 0; i < n; i++) {
          ha[i + 1] = ha[i] * P + s[i];
          pow[i + 1] = pow[i] * P;
        }
    
        int M = 1, m = 10;
        unordered_set<UL> st;
        for (auto& w : ws) {
          M = max(M, (int)w.size());
          m = min(m, (int)w.size());
          UL h = 0;
          for (char ch : w) h = h * P + ch;
          st.insert(h);
        }
    
        vector<bool> mark(s.size());
        for (int i = m - 1; i < n; i++)
          // 只枚举长度在[m, M]的范围
    	  for (int j = i - M + 1; j <= i - m + 1; j++) {
            if (j < 0) continue;
            UL h = ha[i + 1] - ha[j] * pow[i - j + 1];
            if (st.count(h)) {
              for (int k = j; k <= i; k++) mark[k] = true;
              break;
            }
          }
    
        string res;
        for (int i = 0; i < n; i++)
          if (!mark[i]) res += s[i];
          else {
            res += "";
            while (i < n && mark[i]) res += s[i++];
            res += "";
            i--;
          }
    
        return res;
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    时间复杂度 O ( ∑ l A i + n max ⁡ l A i ) O(\sum l_{A_i}+n\max l_{A_i}) O(lAi+nmaxlAi),空间 O ( l A + n ) O(l_A+n) O(lA+n)

  • 相关阅读:
    IDEA中如果优雅Debug
    ChatGPT是如何产生心智的?
    Bash变量--用户自定义变量
    19c-rac环境安装AHF
    【译】在 ASP.NET 和 ASP.NET Core 之间共享代码
    List执行remove操作间歇性报错UnsupportedOperationException
    c++单例模式线程安全几种实现方式
    【Linux学习】跨平台开发 Linux + VS2019 环境配置(Ubantu16.04)
    Roguelike 游戏中的计算哲学
    JAVA常用stream流操作demo演示
  • 原文地址:https://blog.csdn.net/qq_46105170/article/details/128170932