Sometimes people repeat letters to represent extra feeling, such as "hello" -> "heeellooo", "hi" -> "hiiii". In these strings like "heeellooo", we have groups of adjacent letters that are all the same: "h", "eee", "ll", "ooo".
For some given string S
, a query word is stretchy if it can be made to be equal to S
by any number of applications of the following extension operation: choose a group consisting of characters c
, and add some number of characters c
to the group so that the size of the group is 3 or more.
For example, starting with "hello", we could do an extension on the group "o" to get "hellooo", but we cannot get "helloo" since the group "oo" has size less than 3. Also, we could do another extension like "ll" -> "lllll" to get "helllllooo". If S = "helllllooo"
, then the query word "hello" would be stretchy because of these two extension operations: query = "hello" -> "hellooo" -> "helllllooo" = S
.
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 size 3 or more.
Notes:
0 <= len(S) <= 100
.0 <= len(words) <= 100
.0 <= len(words[i]) <= 100
.S
and all words inwords
consist only of lowercase letters
分析
这道题好像是面试中的高频题目,很容易由于边界条件考虑的不全导致写错。刚开始的时候考虑是否可以对S和word进行压缩比较压缩后的字符串是否相同,但是这样的解法行不通,因为word可能重复字符的长度大于S的重复子串。
所以只能一一比较S和word,比较的方法是使用两个指针遍历S和word,每当到新的字符时,向后寻找重复的字符的长度分别获取重复字符的长度为sl和wl,要求sl == wl || (sl != wl && sl >= 3)。一直寻找到字符串的末尾,为了方便查找,可以在字符串的末尾添加‘#’作为结束符,方便查找。
Code
class Solution {
public:
int expressiveWords(string S, vector<string>& words) {
int res = 0;
if (S.size() == 0)
return 0;
S.push_back('#');
int sLen = S.size();
for (int i = 0; i < words.size(); i ++)
{
words[i].push_back('#');
int wLen = words[i].size();
if (wLen > sLen || words[i][0] != S[0])
continue;
int sp = 0;
int sc = 0;
int wp = 0;
int wc = 0;
while (sp < sLen && wp < wLen)
{
while (sp < sLen-1)
{
if (S[sp+1] != S[sp])
break;
sp ++;
}
while (wp < wLen)
{
if (words[i][wp+1] != words[i][wp])
break;
wp ++;
}
if (wp - wc > sp -sc || (sp -sc > wp -wc && sp -sc + 1 < 3))
break;
wp ++;
sp ++;
wc = wp;
sc = sp;
}
cout << endl;
if (wp == wLen && sp == sLen)
res ++;
}
return res;
}
};
运行效率
Runtime: 8 ms, faster than 93.08% of C++ online submissions for Expressive Words.
Memory Usage: 9.4 MB, less than 54.30% of C++ online submissions forExpressive Words.