Bold Words in String

medium strings intervals trie

Problem

Given a list of words and a string s, surround in <b></b> tags any substring of s that matches a word. Overlapping or adjacent bold segments merge into one.

Inputwords=['ab','bc'], s='aabcd'
Output'a<b>abc</b>d'
Positions 1-3 are covered by 'ab' and 'bc' overlapping.

def boldWords(words, s):
    n = len(s)
    mask = [False]*n
    for w in words:
        i = s.find(w)
        while i != -1:
            for j in range(i, i+len(w)): mask[j] = True
            i = s.find(w, i+1)
    out = []
    i = 0
    while i < n:
        if mask[i]:
            j = i
            while j < n and mask[j]: j += 1
            out.append("<b>" + s[i:j] + "</b>")
            i = j
        else:
            out.append(s[i]); i += 1
    return "".join(out)
function boldWords(words, s) {
  const n = s.length, mask = new Array(n).fill(false);
  for (const w of words) {
    let i = s.indexOf(w);
    while (i !== -1) {
      for (let j = i; j < i+w.length; j++) mask[j] = true;
      i = s.indexOf(w, i+1);
    }
  }
  let out = "", i = 0;
  while (i < n) {
    if (mask[i]) {
      let j = i;
      while (j < n && mask[j]) j++;
      out += "<b>" + s.slice(i,j) + "</b>"; i = j;
    } else { out += s[i++]; }
  }
  return out;
}
String boldWords(String[] words, String s) {
    int n = s.length();
    boolean[] mask = new boolean[n];
    for (String w : words) {
        int i = s.indexOf(w);
        while (i != -1) {
            for (int j = i; j < i+w.length(); j++) mask[j] = true;
            i = s.indexOf(w, i+1);
        }
    }
    StringBuilder out = new StringBuilder();
    int i = 0;
    while (i < n) {
        if (mask[i]) {
            int j = i;
            while (j < n && mask[j]) j++;
            out.append("<b>").append(s, i, j).append("</b>"); i = j;
        } else out.append(s.charAt(i++));
    }
    return out.toString();
}
string boldWords(vector<string>& words, string s) {
    int n = s.size();
    vector<bool> mask(n, false);
    for (auto& w : words) {
        size_t i = s.find(w);
        while (i != string::npos) {
            for (size_t j = i; j < i+w.size(); j++) mask[j] = true;
            i = s.find(w, i+1);
        }
    }
    string out; int i = 0;
    while (i < n) {
        if (mask[i]) {
            int j = i;
            while (j < n && mask[j]) j++;
            out += "<b>" + s.substr(i, j-i) + "</b>"; i = j;
        } else out += s[i++];
    }
    return out;
}
Time: O(n*S) Space: O(n)