[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:

  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 = 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;
    }
};

 

類似題目:

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 題目講解匯總(持續更新中...) 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM