[LeetCode] Expressive Words 富於表現力的單詞


 

Sometimes people repeat letters to represent extra feeling, such as "hello" -> "heeellooo", "hi" -> "hiiii".  Here, we have groups, of adjacent letters that are all the same character, and adjacent characters to the group are different.  A group is extended if that group is length 3 or more, so "e" and "o" would be extended in the first example, and "i" would be extended in the second example.  As another example, the groups of "abbcccaaaa" would be "a", "bb", "ccc", and "aaaa"; and "ccc" and "aaaa" are the extended groups of that string.

For some given string S, a query word is stretchy if it can be made to be equal to S by extending some groups.  Formally, we are allowed to repeatedly choose a group (as defined above) of characters c, and add some number of the same character c to it so that the length of the group is 3 or more.  Note that we cannot extend a group of size one like "h" to a group of size two like "hh" - all extensions must leave the group extended - ie., at least 3 characters long.

Given a list of query words, return the number of words that are stretchy. 

Example:
Input: 
S = "heeellooo"
words = ["hello", "hi", "helo"]
Output: 1
Explanation: 
We can extend "e" and "o" in the word "hello" to get "heeellooo".
We can't extend "helo" to get "heeellooo" because the group "ll" is not extended.

Notes:

  • 0 <= len(S) <= 100.
  • 0 <= len(words) <= 100.
  • 0 <= len(words[i]) <= 100.
  • S and all words in words consist only of lowercase letters

 

這道題定義了一種富於表現力的單詞,就是說某個字母可以重復三次或以上,那么對於這種重復后的單詞,我們稱之為可拉伸的(stretchy)。現在給了我們一個拉伸后的單詞S,又給了我們一個單詞數組,問我們里面有多少個單詞可以拉伸成為S。其實這道題的關鍵就在於看某個字母是否被重復了三次,重復兩次是不行的。那么我們就只能遍歷單詞數組words中的單詞,來分別和S比較了。每個遍歷到的單詞的長度suppose是應該小於等於S的,因為S是拉伸后的單詞,當然S也可以和遍歷到的單詞相等,那么表示沒有拉伸。我們需要兩個指針i和j來分別指向S和遍歷單詞word,我們需要逐個比較,由於S的長度要大於等於word,所以我們for循環直接遍歷S的字母就好了,首先看如果j沒越界,並且此時S[i]和word[j]相等的話,那么j自增1,i在for循環中也會自增1,遍歷下一個字母。如果此時不相等或者j已經越界的話,我們再看當前的S[i]是否是3個重復中的中間那個,即S[i-1]和S[i+1]需要等於S[i],是的話,i自增1,然后加上for循環中的自增1,相當於總共增了2個,正好跳過這個重復三連。否則的話再看是否前兩個都和當前的字母相等,即S[i-1]和S[i-2]需要等於S[i],因為可能重復的個數多於3個,如果這個條件不滿足的話,直接break就行了。for循環結束或者跳出后,我們看S和word是否正好遍歷完,即i和j是否分別等於S和word的長度,是的話結果res自增1,參見代碼如下:

 

class Solution {
public:
    int expressiveWords(string S, vector<string>& words) {
        int res = 0, m = S.size(), n = words.size();
        for (string word : words) {
            int i = 0, j = 0;
            for (; i < m; ++i) {
                if (j < word.size() && S[i] == word[j]) ++j;
                else if (i > 0 && S[i] == S[i - 1] && i + 1 < m && S[i] == S[i + 1]) ++i;
                else if (!(i > 1 && S[i] == S[i - 1] && S[i] == S[i - 2])) break;
            }
            if (i == m && j == word.size()) ++res;
        }
        return res;
    }
};

 

參考資料:

https://leetcode.com/problems/expressive-words/discuss/122660/C++JavaPython-2-Pointers-and-4-pointers

https://leetcode.com/problems/expressive-words/discuss/121741/Short-straight-forward-C++-solution-two-pointers-one-pass-scan

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

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



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