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:

  1. words has length in range [0, 50].
  2. words[i] has length in range [1, 10].
  3. S has length in range [0, 500].
  4. All characters in words[i] and S 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 = ; i <= n - len; ++i) {
if (S[i] == word[] && S.substr(i, len) == word) {
for (int j = i; j < i + len; ++j) bold[j] = true;
}
}
}
for (int i = ; i < n; ++i) {
if (bold[i]) {
if (i == || !bold[i - ]) res += "<b>";
res.push_back(S[i]);
if (i == n - || !bold[i + ]) 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 = ; i <= n - len; ++i) {
if (S[i] == word[] && S.substr(i, len) == word) {
for (int j = i; j < i + len; ++j) bold.insert(j);
}
}
}
for (int i = ; i < n; ++i) {
if (bold.count(i) && !bold.count(i - )) res += "<b>";
res.push_back(S[i]);
if (bold.count(i) && !bold.count(i + )) 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 = ;
string res = "";
vector<bool> bold(n, false);
for (int i = ; 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 = ; 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 - ;
}
return res;
}
};

类似题目:

Add Bold Tag in String

参考资料:

https://leetcode.com/problems/bold-words-in-string/discuss/113107/Java-Solution-without-HashMap

https://leetcode.com/problems/bold-words-in-string/discuss/113093/Clean-Python-and-C++-solutions-with-hashset-to-store-bold-indices

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Bold Words in String 字符串中的加粗单词的更多相关文章

  1. [LeetCode] Add Bold Tag in String 字符串中增添加粗标签

    Given a string s and a list of strings dict, you need to add a closed pair of bold tag <b> and ...

  2. [LeetCode] 567. Permutation in String 字符串中的全排列

    Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...

  3. String 字符串中含有 Unicode 编码时,转为UTF-8

    1.单纯的Unicode 转码 String a = "\u53ef\u4ee5\u6ce8\u518c"; a = new String(a.getBytes("UTF ...

  4. 将string字符串中的换行符进行替换

    /** * 方法名称:replaceBlank * 方法描述: 将string字符串中的换行符进行替换为"" * */ public static String replaceBl ...

  5. JS返回一个字符串中长度最小的单词的长度

    题目:编写一个方法,返回字符串中最小长度的单词的长度. var str = 'What a good day today!'; 1 //方法一 2 function returnString1(str ...

  6. [LeetCode] Permutation in String 字符串中的全排列

    Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...

  7. 434 Number of Segments in a String 字符串中的单词数

    统计字符串中的单词个数,这里的单词指的是连续的非空字符.请注意,你可以假定字符串里不包括任何不可打印的字符.示例:输入: "Hello, my name is John"输出: 5 ...

  8. [CareerCup] 1.1 Unique Characters of a String 字符串中不同的字符

    1.1 Implement an algorithm to determine if a string has all unique characters. What if you cannot us ...

  9. String:(字符串)中常用的方法

    package stringyiwen; //字符串中常用的方法public class StringTest03 { public static void main(String[] args) { ...

随机推荐

  1. [poj1012]Joseph_Joseph

    Joseph 题目大意:给你2*k个人,前k个是好人,后k个是坏人,编号从1到2*k.每次从上一个死掉的人的下一个开始查m个人并将第m个人杀死.问最后剩下的全是好人的m是多少. 注释:$1\le k ...

  2. [luogu1402]酒店之王_网络流

    酒店之王 luogu-1402 题目大意:有n个人,p道菜,q个房间,每个人喜欢吃一些菜.喜欢住一些房间,如果一个人即住到了他喜欢的房间有吃到了他喜欢的菜,就对答案贡献++,求最大贡献. 注释:1&l ...

  3. C#中的String类

    一.String类的方法 1. Trim():清除字符串两端的空格 2. ToLower():将字符串转换为小写 3. Equals():比较两个字符串的值,bool 4. IndexOf(value ...

  4. css代码整理

    width:(宽度) height:(高度) border:1px solid red:(边框 :边框粗细 显示 颜色) border-radius:10deg:(边框变圆角) box-shadow: ...

  5. C语言博客作业—函数嵌套调用

    一.实验作业 1.1 PTA题目:递归法对任意10个数据按降序排序 1.1.1设计思路 void sort(int a[],int n) { 定义整型循环变量i,中间变量temp,最小值min: 令m ...

  6. vivado License导入方法与资源获取

    前言 以下安装说明基于已经正确安装vivado 笔者操作环境:linux vivado版本:2015.2 vivado License导入方法: 点击菜单栏[Help],选择[Manage Licen ...

  7. Ubuntu下tomcat或eclipse启动提示没有java环境问题

    tomcat和eclipse默认使用了openjdk,通过压缩包安装的jdk无法被识别,通过修改tomcat/bin下的catalina.sh添加jdk和jre路径即可 sudo gedit cata ...

  8. 解决SoapFault (looks like we got no XML document)问题

    今天在调试项目的时候出现下面的错误信息: SoapFault looks like we got no XML document (D:\phpStudy\WWW\self.shop.xunmall. ...

  9. Electron的代码调试

    刚接触Electron,尝试调试程序时,竟无从下手,所以把这个过程做了下记录 参考工程 根据Electron的官方文档:使用 VSCode 进行主进程调试:https://electronjs.org ...

  10. Hadoop2.6.0实践:001 伪分布式环境搭建

    ##################### Centos6.4VM_01_os.rar ################################################准备工作/opt ...