1
- // Time: O(s * d * l), l is the average string length
2
- // Space: O(s )
1
+ // Time: O(n * d * l), l is the average string length
2
+ // Space: O(n )
3
3
4
+ // 16ms
4
5
class Solution {
5
6
public:
6
7
string addBoldTag (string s, vector<string>& dict) {
@@ -24,3 +25,71 @@ class Solution {
24
25
return result;
25
26
}
26
27
};
28
+
29
+ // Time: O(n * l), l is the average string length
30
+ // Space: O(t) , t is the size of trie
31
+ // 142ms
32
+ class Solution2 {
33
+ public:
34
+ string addBoldTag (string s, vector<string>& dict) {
35
+ TrieNode trie;
36
+ for (const auto & word : dict) {
37
+ trie.Insert (word);
38
+ }
39
+
40
+ vector<bool > lookup (s.length ());
41
+ for (int i = 0 ; i < s.length (); ++i) {
42
+ auto curr = ≜
43
+ int k = i - 1 ;
44
+ for (int j = i; j < s.length (); ++j) {
45
+ if (!curr->leaves .count (s[j])) {
46
+ break ;
47
+ }
48
+ curr = curr->leaves [s[j]];
49
+ if (curr->isString ) {
50
+ k = j;
51
+ }
52
+ }
53
+ fill (lookup.begin () + i, lookup.begin () + k + 1 , true );
54
+ }
55
+
56
+ string result;
57
+ for (int i = 0 ; i < s.length (); ++i) {
58
+ if (lookup[i] && (i == 0 || !lookup[i - 1 ])) {
59
+ result += " <b>" ;
60
+ }
61
+ result.push_back (s[i]);
62
+ if (lookup[i] && (i == (s.length () - 1 ) || !lookup[i + 1 ])) {
63
+ result += " </b>" ;
64
+ }
65
+ }
66
+ return result;
67
+ }
68
+
69
+ private:
70
+ struct TrieNode {
71
+ bool isString;
72
+ unordered_map<char , TrieNode *> leaves;
73
+
74
+ TrieNode () : isString{false } {}
75
+
76
+ void Insert (const string& s) {
77
+ auto * p = this ;
78
+ for (const auto & c : s) {
79
+ if (!p->leaves [c]) {
80
+ p->leaves [c] = new TrieNode;
81
+ }
82
+ p = p->leaves [c];
83
+ }
84
+ p->isString = true ;
85
+ }
86
+
87
+ ~TrieNode () {
88
+ for (auto & kvp : leaves) {
89
+ if (kvp.second ) {
90
+ delete kvp.second ;
91
+ }
92
+ }
93
+ }
94
+ };
95
+ };
0 commit comments