class Solution:
def addBoldTag(self, s: str, words: List[str]) -> str:
n = len(s)
bold = [False] * n
for word in words:
start = s.find(word)
while start != -1:
for i in range(start, start + len(word)):
bold[i] = True
start = s.find(word, start + 1)
res = []
i = 0
while i < n:
if bold[i]:
res.append("<b>")
while i < n and bold[i]:
res.append(s[i])
i += 1
res.append("</b>")
else:
res.append(s[i])
i += 1
return "".join(res)
class Solution {
public:
string addBoldTag(string s, vector<string>& words) {
int n = s.size();
vector<bool> bold(n, false);
for (const string& word : words) {
size_t pos = s.find(word);
while (pos != string::npos) {
for (int i = pos; i < pos + word.size(); ++i)
bold[i] = true;
pos = s.find(word, pos + 1);
}
}
string res;
int i = 0;
while (i < n) {
if (bold[i]) {
res += "<b>";
while (i < n && bold[i]) {
res += s[i];
++i;
}
res += "</b>";
} else {
res += s[i++];
}
}
return res;
}
};
class Solution {
public String addBoldTag(String s, String[] words) {
int n = s.length();
boolean[] bold = new boolean[n];
for (String word : words) {
int start = s.indexOf(word);
while (start != -1) {
for (int i = start; i < start + word.length(); i++) {
bold[i] = true;
}
start = s.indexOf(word, start + 1);
}
}
StringBuilder res = new StringBuilder();
int i = 0;
while (i < n) {
if (bold[i]) {
res.append("<b>");
while (i < n && bold[i]) {
res.append(s.charAt(i));
i++;
}
res.append("</b>");
} else {
res.append(s.charAt(i));
i++;
}
}
return res.toString();
}
}
var addBoldTag = function(s, words) {
const n = s.length;
const bold = Array(n).fill(false);
for (const word of words) {
let start = s.indexOf(word);
while (start !== -1) {
for (let i = start; i < start + word.length; i++) {
bold[i] = true;
}
start = s.indexOf(word, start + 1);
}
}
let res = '';
let i = 0;
while (i < n) {
if (bold[i]) {
res += '<b>';
while (i < n && bold[i]) {
res += s[i];
i++;
}
res += '</b>';
} else {
res += s[i];
i++;
}
}
return res;
};
Given a string s
and an array of strings words
, you need to wrap all substrings in s
that match any word in words
with a bold HTML tag: <b>...</b>
. If two or more matching substrings overlap or are adjacent, you should wrap them together with a single pair of bold tags. The output should be the resulting string with the appropriate bold tags inserted.
words
can be used multiple times, as long as it matches a substring in s
.
The first idea that comes to mind is to look for every occurrence of each word in words
within the string s
, and for each match, insert <b>
and </b>
around it. However, this approach quickly becomes tricky because inserting tags changes the string's indices, making further searches unreliable.
Also, since matches can overlap or touch each other, inserting tags immediately might result in nested or redundant tags. Therefore, we need a way to mark which characters in s
should be bolded, and then do a single pass to insert tags at the correct places, merging overlapping or adjacent ranges.
To optimize, instead of repeatedly modifying the string, we can use an auxiliary array to track which characters should be bold, and then construct the final string in one go.
bold
of the same length as s
. For each word in words
, search for all occurrences in s
. For each match, mark the corresponding positions in bold
as True
.
bold
array now represents which characters need to be wrapped in a bold tag. Adjacent or overlapping matches will have consecutive True
values.
s
with the bold
array. When entering a bold region (i.e., bold[i]
is True
and i == 0
or bold[i-1]
is False
), insert <b>
. When leaving a bold region (i.e., bold[i]
is True
and i == n-1
or bold[i+1]
is False
), insert </b>
.
This approach ensures we only scan the string a couple of times, and merging of bold regions is handled naturally by the bold
array.
Input: s = "abcxyz123"
, words = ["abc","123"]
bold[0]
, bold[1]
, bold[2]
as True
.bold[6]
, bold[7]
, bold[8]
as True
.bold
array is now: [True, True, True, False, False, False, True, True, True]
<b>
</b>
<b>
</b>
<b>abc</b>xyz<b>123</b>
s
, M is the number of words, and L is the average word length.
s
to find all occurrences. This is O(N * M * L) in the worst case.s
, O(N).bold
array and output string.
The solution marks all characters in s
that need to be bold using a boolean array, then constructs the output by inserting bold tags only at the boundaries of these regions. This avoids the pitfalls of modifying the string in place and elegantly handles overlapping or adjacent matches. The approach is straightforward, efficient for typical constraints, and easy to understand.