1. 题目
给定一个关键词集合 words 和一个字符串 S,将所有 S 中出现的关键词加粗。所有在标签 <b> 和 </b>
中的字母都会加粗。
返回的字符串需要使用尽可能少的标签,当然标签应形成有效的组合。
例如,给定 words = ["ab", "bc"] 和 S = "aabcd"
,需要返回 "a<b>abc</b>d"
。注意返回 "a<b>a<b>b</b>c</b>d"
会使用更多的标签,因此是错误的。
注:
words 长度的范围为 [0, 50]。
words[i] 长度的范围为 [1, 10]。
S 长度的范围为 [0, 500]。
所有 words[i] 和 S 中的字符都为小写字母。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bold-words-in-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
同样题目:LeetCode 616. 给字符串添加加粗标签(Trie树)
- 将集合里的单词全部插入trie树
- 以S的每个位置为起点在trie树开始查找完整单词,记录可以加黑的地方,标记在bool数组里
class trie
{
public:
trie* next[26] = {NULL};
bool isend = false;
int count = 0;
void insert(string& s)
{
trie* cur = this;
for(int i = 0; i < s.size(); i++)
{
if(cur->next[s[i]-'a'] == NULL)
cur->next[s[i]-'a'] = new trie();
cur = cur->next[s[i]-'a'];
}
cur->count++;
cur->isend = true;
}
};
class Solution {
public:
string boldWords(vector<string>& words, string S) {
trie *t = new trie(), *cur;
for(auto& w : words)
t->insert(w);
vector<bool> bold(S.size(), false);//加黑标记
int boldl = 0, boldr=-1;//开始加粗的位置l,r
for(int i = 0, j; i < S.size(); ++i)
{
cur = t;
boldl = max(boldl, i);//加黑的地方左端点
j = i;
while(j < S.size() && cur && cur->next[S[j]-'a'])
{
cur = cur->next[S[j]-'a'];
if(cur->isend)
boldr = j;//可以加黑的右端点
j++;
}
while(boldl <= boldr)
bold[boldl++] = true;//标记加黑
}
string ans;
for(int i = 0; i < S.size(); ++i)
{
if((i==0 && bold[i]) || (i>0 && !bold[i-1] && bold[i]))//i起点
ans += "<b>";
ans += S[i];
if((i==S.size()-1 && bold[i]) || (i<S.size()-1 && bold[i] && !bold[i+1]))//i是终点
ans += "</b>";
}
return ans;
}
};
12 ms 11.2 MB
长按或扫码关注我的公众号,一起加油、一起学习进步!