分析单词可扩张条件 :
对于某个字母,设目标字母长度
c
1
c1
c1 ,待扩张字母长度
c
2
c2
c2
当
c
1
<
c
2
c1
当
c
1
≥
c
2
c1\ge c2
c1≥c2,目标字母比待扩张字母多或者相等,如果
c
1
≥
3
c1\ge3
c1≥3 可以扩张。如果
c
1
<
3
c1<3
c1<3 ,仅当
c
2
=
c
1
c2=c1
c2=c1 ,字母数量相等,等价于“可扩张”。
算法流程:
class Solution {
public:
int expressiveWords(string s, vector<string>& words) {
int ans = 0;
if(s.empty()){
for(auto &w:words)
if(w.empty()) ans++;
return ans;
}
vector<pair<char,int>> p;
for(int i = 0;i<s.size();i++){
int j = i + 1;
while(j<s.size()&&s[i]==s[j]) j++;
p.push_back({s[i],j-i});
i = j-1;
}
for(auto &w:words){
int k = 0;//k指向p
for(int i = 0 ;i<w.size();i++){//i指向w
if(p.size()==k) {//p遍历完,w还没遍历完
k= -1;
break;
}
if(w[i]!=p[k].first) break;
int j = i + 1;
while(j<w.size()&&w[i]==w[j]) j++;
int c1 = p[k].second, c2 = j - i;
if(c1<c2) break;
if(c1<3&&c1!=c2) break;
k++,i = j - 1;
}
if(p.size()==k) ans++;//w和p同时遍历完
}
return ans;
}
};
时间复杂度 O ( m + ∑ i = 0 n − 1 w o r d s i ) O(m +\sum_{i=0}^{n-1}words_i) O(m+∑i=0n−1wordsi) , n n n 是单词数量, m m m 是待扩张字符串的长度。遍历每个单词的时间复杂度 O ( ∑ i = 0 n − 1 w o r d s i ) O(\sum_{i=0}^{n-1}words_i) O(∑i=0n−1wordsi) ,遍历 s s s 的时间复杂度 O ( m ) O(m) O(m) ,总时间复杂度 O ( m + ∑ i = 0 n − 1 w o r d s i ) O(m +\sum_{i=0}^{n-1}words_i) O(m+∑i=0n−1wordsi)。
空间复杂度 O ( m ) O(m) O(m) ,保存 s s s 的字母组的最坏空间复杂度 O ( m ) O(m) O(m) 。
理解思路很重要。
欢迎读者在评论区留言,答主看到就会回复的。