You are given a string s
and an array of strings words
. You should add a bold tag <b>
and </b>
to all the substrings of s
that are present in words
.
Return s
after adding the bold tags.
You can return any valid answer. It is guaranteed that adding the tags won't change the length of the string.
Example 1:
Input: s = "abcxyz123", words = ["abc","xyz"] Output: "<b>abc</b><b>xyz</b>123" Explanation: The strings "abc", and "xyz" exist in the string s, so they are surrounded by appropriate bold tags.
Example 2:
Input: s = "aaabbcc", words = ["aaa","aab","bc"] Output: "<b>aaabbc</b>c"
Constraints:
1 <= s.length <= 500
0 <= words.length <= 100
1 <= words[i].length <= 50
s
and words[i]
consist of lowercase English letters and digits.words
are unique.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for adding bold tags involves checking every possible position in the input string to see if any of the words we're looking for start at that position. For each position, we'll need to determine if we should add a bold tag.
Here's how the algorithm would work step-by-step:
def add_bold_tag_brute_force(string, words):
string_length = len(string)
bold_indices = [False] * string_length
# Mark indices that need to be bolded
for index in range(string_length):
for word in words:
if string[index:].startswith(word):
# Mark indices corresponding to the matched word as True
for word_index in range(len(word)):
bold_indices[index + word_index] = True
merged_string = ""
bold_tag_open = False
for index in range(string_length):
if bold_indices[index] and not bold_tag_open:
# Add open tag if current index is bold and tag is closed
merged_string += "<b>"
bold_tag_open = True
elif not bold_indices[index] and bold_tag_open:
# Close tag if current index is not bold and tag is open
merged_string += "</b>"
bold_tag_open = False
merged_string += string[index]
# Close tag if it's still open at the end of the string
if bold_tag_open:
merged_string += "</b>"
return merged_string
The core idea is to identify the portions of the string that need to be bolded by tracking which characters match the bold word list. Then, we merge overlapping or adjacent bold sections to minimize the number of bold tags we need to insert. Finally, we walk through the string and insert the necessary bold tags.
Here's how the algorithm would work step-by-step:
def add_bold_tag(string, dictionary):
string_length = len(string)
bold_flags = [False] * string_length
for word in dictionary:
for i in range(string_length - len(word) + 1):
if string[i:i+len(word)] == word:
# Mark characters as bold if word is found
for j in range(i, i + len(word)):
bold_flags[j] = True
merged_intervals = []
i = 0
while i < string_length:
if not bold_flags[i]:
i += 1
continue
start = i
while i < string_length and bold_flags[i]:
i += 1
end = i
# Merge overlapping intervals into a single interval
if merged_intervals and start <= merged_intervals[-1][1]:
merged_intervals[-1] = (merged_intervals[-1][0], max(end, merged_intervals[-1][1]))
else:
merged_intervals.append((start, end))
result = ""
current_index = 0
for start, end in merged_intervals:
result += string[current_index:start]
result += "<b>"
result += string[start:end]
result += "</b>"
current_index = end
#Append the remainder of the string
result += string[current_index:]
return result
Case | How to Handle |
---|---|
Null string or null array of words | Return the original string if either the string or the words array are null to avoid NullPointerException. |
Empty string or empty array of words | Return the original string if the input string is empty or if the array of words is empty as there is nothing to bold. |
Words array contains empty strings | Ignore empty strings in the words array to prevent unexpected behavior in the matching logic. |
Words array contains duplicate strings | The algorithm should correctly handle duplicate words, potentially bolding the same region multiple times (which is acceptable). |
Overlapping words in the string | The algorithm needs to merge overlapping bold tags to produce a minimal and correct result. |
Very long input string and a large number of words | Ensure the time complexity of the solution is efficient (e.g., avoid brute-force search) to handle large inputs without timing out. |
Words contain special characters or regular expression metacharacters | Escape special characters in the words before using them in regular expression matching to avoid incorrect results. |
Input string or words contain Unicode characters | Ensure the string comparison and manipulation are Unicode-aware to correctly handle non-ASCII characters. |