Watch 9 video solutions for Add Bold Tag in String, a medium level problem involving Array, Hash Table, String. This walkthrough by Happy Coding has 4,453 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
You are given a string s and an array of strings words.
You should add a closed pair of bold tag <b> and </b> to wrap the substrings in s that exist in words.
Return s after adding the bold tags.
Example 1:
Input: s = "abcxyz123", words = ["abc","123"] Output: "<b>abc</b>xyz<b>123</b>" Explanation: The two strings of words are substrings of s as following: "abcxyz123". We add <b> before each substring and </b> after each substring.
Example 2:
Input: s = "aaabbb", words = ["aa","b"] Output: "<b>aaabbb</b>" Explanation: "aa" appears as a substring two times: "aaabbb" and "aaabbb". "b" appears as a substring three times: "aaabbb", "aaabbb", and "aaabbb". We add <b> before each substring and </b> after each substring: "<b>a<b>a</b>a</b><b>b</b><b>b</b><b>b</b>". Since the first two <b>'s overlap, we merge them: "<b>aaa</b><b>b</b><b>b</b><b>b</b>". Since now the four <b>'s are consecutive, we merge them: "<b>aaabbb</b>".
Constraints:
1 <= s.length <= 10000 <= words.length <= 1001 <= words[i].length <= 1000s and words[i] consist of English letters and digits.words are unique.
Note: This question is the same as 758. Bold Words in String.
Problem Overview: Given a string s and a list of dictionary words, wrap every substring in s that appears in the dictionary with <b> and </b>. Overlapping or adjacent matches must be merged into a single bold region.
Approach 1: Brute Force Matching + Interval Merge (O(n * k * L) time, O(n) space)
Scan the string from every index and check whether any dictionary word matches starting at that position using substring comparison. For each match, mark the covered indices in a boolean array or store intervals like [start, end]. After processing all matches, merge overlapping or adjacent intervals and construct the final string by inserting <b> and </b> around bold segments. This approach is straightforward and easy to implement, but repeated substring comparisons make it slower when the dictionary is large.
Approach 2: Boolean Marking with Longest Match Tracking (O(n * k * L) time, O(n) space)
Instead of storing intervals, maintain a boolean array bold[i] indicating whether character i should be bold. While iterating through s, check every dictionary word with a prefix comparison like s.startswith(word, i). Track the farthest index that should remain bold and mark characters up to that boundary. Finally, build the output string while opening a <b> tag when entering a bold region and closing it when leaving one. This method avoids explicit interval merging and is often the cleanest implementation.
Approach 3: Trie-Based String Matching (O(n * L) time, O(W * L) space)
Build a Trie from the dictionary words. Starting at each index in s, traverse the Trie while characters continue to match. Whenever a word end is reached, update the farthest bold boundary. This reduces redundant comparisons because common prefixes are shared in the Trie. The technique is common in string matching problems and works well when the dictionary contains many overlapping prefixes. Use an array or interval list to mark bold positions and generate the final string.
Recommended for interviews: The boolean marking approach is usually expected. It demonstrates clear reasoning about substring matching and interval merging while keeping the implementation simple. Mentioning a Trie optimization shows deeper understanding of scalable string matching techniques.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Matching + Interval Merge | O(n * k * L) | O(n) | Good for understanding the problem and when dictionary size is small |
| Boolean Marking with Longest Match | O(n * k * L) | O(n) | Clean implementation for interviews; avoids explicit interval merging |
| Trie-Based String Matching | O(n * L) | O(W * L) | Best when dictionary has many words with shared prefixes |