Given an array of keywords words and a string s, make all appearances of the keywords (each as a substring) in s bold. Any letters are covered by more than one keyword should be covered by only one pair of <b> and </b> tags. Return s after adding the bold tags.
Example 1:
Input: words = ["abc","bcd","abcd"], s = "abcxyzzabcdabcdabc"
Output: "<b>abc</b>xyzz<b>abcd</b><b>abcdabc</b>"
Example 2:
Input: words = ["ab","cb"], s = "abcxyz123"
Output: "<b>ab</b>cxyz123"
Constraints:
1 <= s.length <= 5000 <= words.length <= 501 <= words[i].length <= 10s and words[i] consist of lowercase English letters.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 approach involves checking every possible combination to identify which parts of a string need to be bolded. We go through the string and each individual word to see if that word exists in the string. If we find the word, we highlight those parts to be bolded.
Here's how the algorithm would work step-by-step:
def bold_words_brute_force(string, words):
string_length = len(string)
bold_mask = [False] * string_length
# Iterate through each starting position in the string
for starting_position in range(string_length):
# Check each word in our dictionary
for word in words:
if string[starting_position:].startswith(word):
# Mark the substring to be bolded
for i in range(len(word)):
bold_mask[starting_position + i] = True
result = ""
bold = False
for i in range(string_length):
if bold_mask[i] and not bold:
result += "<b>"
bold = True
elif not bold_mask[i] and bold:
# Close the bold tag when needed
result += "</b>"
bold = False
result += string[i]
if bold:
result += "</b>"
return resultThe goal is to highlight specific words within a larger string by wrapping them in bold tags. The clever approach is to first mark the start and end positions where bolding should occur and then construct the final string based on these marked positions. This avoids repeatedly searching for the words.
Here's how the algorithm would work step-by-step:
def bold_words_in_string(string_to_bold, words_to_bold):
string_length = len(string_to_bold)
bold_marker = [False] * string_length
for word in words_to_bold:
for index in range(string_length - len(word) + 1):
if string_to_bold[index:index + len(word)] == word:
# Mark the positions to be bolded
for marker_index in range(index, index + len(word)):
bold_marker[marker_index] = True
merged_markers = []
start_index = -1
for index, should_bold in enumerate(bold_marker):
if should_bold and start_index == -1:
start_index = index
elif not should_bold and start_index != -1:
merged_markers.append((start_index, index))
start_index = -1
if start_index != -1:
merged_markers.append((start_index, string_length))
result = ""
marker_index = 0
for index in range(string_length):
if marker_index < len(merged_markers) and index == merged_markers[marker_index][0]:
# Insert bold tag at the start
result += "<b>"
result += string_to_bold[index]
if marker_index < len(merged_markers) and index == merged_markers[marker_index][1] - 1:
# Insert closing bold tag at the end
result += "</b>"
marker_index += 1
return result| Case | How to Handle |
|---|---|
| words array is empty | Return the original string since there are no words to bold. |
| s is empty | Return an empty string, as there's nothing to bold in an empty string. |
| s is null or words is null | Throw IllegalArgumentException to indicate invalid input. |
| words contains an empty string | Treat the empty string as matching anything, resulting in the entire string 's' being bolded. |
| words contains duplicates | The algorithm should still function correctly, potentially increasing the number of bolded sections if overlaps exist. |
| words contains overlapping matches in s | The solution must correctly merge overlapping bolded sections into single, larger bolded sections. |
| s is very long and words is very large, potentially exceeding memory limits or causing a timeout. | The chosen algorithm (e.g., using boolean array marking) must have reasonable time and space complexity (ideally O(n*m) where n is len(s) and m is the total length of all words). |
| No word in 'words' exists in 's' | Return the original string 's' unmodified, as there are no words to bold. |