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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| class Solution { public: string addBoldTag(string s, vector<string>& dict) { root = new TrieNode; for (const auto &w : dict) { add(w); } for (int n = s.length(), r = 0; r < n; ++r) { add(search(s, r), r); } string res; for (int n = s.length(), i = 0; i < n; ++i) { if (!lst.empty()) { auto [l, r] = lst.front(); if (i == l) { res += "<b>"; } if (i == r) { res += s[i]; res += "</b>"; lst.pop_front(); continue; } } res += s[i]; } return res; }
struct TrieNode { unordered_map<char, TrieNode *> children; bool isEnd = false; };
TrieNode *root = nullptr;
void add(const string &s) { auto p = root; for (int n = s.length(), i = n - 1; i >= 0; --i) { if (!p->children.count(s[i])) { p->children[s[i]] = new TrieNode; } p = p->children[s[i]]; } p->isEnd = true; }
int search(const string &s, int r) { auto p = root; int l = r + 1; for (int i = r; i >= 0; --i) { if (!p->children.count(s[i])) break; p = p->children[s[i]]; if (p->isEnd) { l = min(l, i); } } return l; }
void add(int l, int r) { if (l > r) return; while (!lst.empty() && l <= lst.back().second + 1) { l = min(l, lst.back().first); lst.pop_back(); } lst.emplace_back(l, r); }
list<pair<int, int>> lst; };
|