[LeetCode] Bold Words in String 字符串中的加粗单词
Given a set of keywords words
and a string S
, make all appearances of all keywords in S
bold. Any letters between <b>
and </b>
tags become bold.
The returned string should use the least number of tags possible, and of course the tags should form a valid combination.
For example, given that words = ["ab", "bc"]
and S = "aabcd"
, we should return "a<b>abc</b>d"
. Note that returning "a<b>a<b>b</b>c</b>d"
would use more tags, so it is incorrect.
Note:
words
has length in range[0, 50]
.words[i]
has length in range[1, 10]
.S
has length in range[0, 500]
.- All characters in
words[i]
andS
are lowercase letters.
这道题跟之前的那道Add Bold Tag in String是一模一样的,之前还换个马甲,这次连场景都不换了,直接照搬啊?!我也是服气的~这道题应该没有太多的技巧,就是照题目意思来就行了,我们使用一个数组bold,标记所有需要加粗的位置为true,初始化所有为false。我们首先要判断每个单词word是否是S的子串,判断的方法就是逐个字符比较,遍历字符串S,找到和word首字符相等的位置,并且比较随后和word等长的子串,如果完全相同,则将子串所有的位置在bold上比较为true。等我们知道了所有需要加粗的位置后,我们就可以来生成结果res了,我们遍历bold数组,如果当前位置是true的话,表示需要加粗,那么我们首先看如果是第一个字符,或者其前面的字符不用加粗,我们加上一个左标签<b>,然后我们将当前字符加入结果res中,然后再判断,如果当前是末尾字符,或者后面一个字符不用加粗,则需要加上一个右标签</b>;如果当前位置是false,我们直接将字符加入结果res中即可,参见代码如下:
解法一:
class Solution { public: string boldWords(vector<string>& words, string S) { int n = S.size(); string res = ""; vector<bool> bold(n, false); for (string word : words) { int len = word.size(); for (int i = 0; i <= n - len; ++i) { if (S[i] == word[0] && S.substr(i, len) == word) { for (int j = i; j < i + len; ++j) bold[j] = true; } } } for (int i = 0; i < n; ++i) { if (bold[i]) { if (i == 0 || !bold[i - 1]) res += "<b>"; res.push_back(S[i]); if (i == n - 1 || !bold[i + 1]) res += "</b>"; } else { res.push_back(S[i]); } } return res; } };
我们可以用HashSet来代替数组,只是将需要加粗的位置放入HashSet,然后我们在生成结果res的时候,先检测当前位置是否加粗,如果加粗了,并且前一个位置不在HashSet中,这样就不用判断是否是第一个元素了,因为i-1肯定不再HashSet中,也不像数组那样存在越界的可能,我们给结果res加上左标签,然后将当前的字符加入结果res中,然后再判断如果当前位置如果加粗了,并且下一个位置不在HashSet中,我们给结果res加上右标签,参见代码如下:
解法二:
class Solution { public: string boldWords(vector<string>& words, string S) { int n = S.size(); string res = ""; unordered_set<int> bold; for (string word : words) { int len = word.size(); for (int i = 0; i <= n - len; ++i) { if (S[i] == word[0] && S.substr(i, len) == word) { for (int j = i; j < i + len; ++j) bold.insert(j); } } } for (int i = 0; i < n; ++i) { if (bold.count(i) && !bold.count(i - 1)) res += "<b>"; res.push_back(S[i]); if (bold.count(i) && !bold.count(i + 1)) res += "</b>"; } return res; } };
前面提到了这道题跟Add Bold Tag in String是完全一样,那么当然二者的解法是互通的,下面的解法是之前那道题中的解法,其实整体思路是一样的,只不过在构建的bold数组的时候,是先遍历的字符串S,而不是先遍历的单词。对于字符串S中的每个字符为起点,我们都遍历下所有单词,如果某个单词是以当前字符为起点的子串的话,那么我们用i+len来更新end,所以遍历完所有单词后,只要当前位置需要加粗,那么end一定大于i,通过这种方法同样也可以生成正确的bold数组。然后在创建结果res字符串的时候也跟上面的方法有些不同,首先判断,如果当前未被加粗,那么将当前字符存入结果res中并且continue,否则开始找相连的需要加粗的位置,用j来指向下一个不用加粗的位置,这样中间的子串就可以放入标签中整体加到res中,然后继续在后面查找连续加粗的子串,参见代码如下:
解法三:
class Solution { public: string boldWords(vector<string>& words, string S) { int n = S.size(), end = 0; string res = ""; vector<bool> bold(n, false); for (int i = 0; i < n; ++i) { for (string word : words) { int len = word.size(); if (i + len <= n && S.substr(i, len) == word) { end = max(end, i + len); } } bold[i] = end > i; } for (int i = 0; i < n; ++i) { if (!bold[i]) { res.push_back(S[i]); continue; } int j = i; while (j < n && bold[j]) ++j; res += "<b>" + S.substr(i, j - i) + "</b>"; i = j - 1; } return res; } };
类似题目:
参考资料:
https://leetcode.com/problems/bold-words-in-string/discuss/113107/Java-Solution-without-HashMap
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
2017-03-08 [LeetCode] 524. Longest Word in Dictionary through Deleting 删除后得到的字典中的最长单词
2017-03-08 3D Slicer 4.7.0 VS 2010 Compile 编译
2016-03-08 [LeetCode] 298. Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
2015-03-08 [LeetCode] 190. Reverse Bits 颠倒二进制位
2015-03-08 [LeetCode] 86. Partition List 分隔链表