今天是520.祝愿天下的程序员们早日脱单,升职加薪,生活幸福美满 ~
题目描述
只要求最长的子串长度,所以我第一时间考虑的是滑动窗口,如果该窗口的长度满足之后就直接返回该长度即可。
思路:
暴力解法:从长至短,遍历所有子串,在每个子串中查询各个元音字符出现的次数。这个肯定超时啊,所以想办法优化一下,超时的原因是什么?是因为每次子串的遍历都要进行元音和辅音字符的判断,那能否减少这样的判断呢?当然可以,我们用数组来表示整个字符串当中所有元音字符出现的位置,这样。我们每次在子串中只遍历元音字符即可~
思路有了,代码其实就不难了
//首先想到的是暴力解法.从最长开始解.如果
//双指针i,j指向头尾,如果这个字符串不满足,就判断i++->j的字符串满足与否, 以及i->j--的字符串满足与否
//记录每个元音字符串的位置.
class Solution {
public:
vector<int> a; //记录a字符出现的在字符串中出现的位置
vector<int> e;
vector<int> i;
vector<int> o;
vector<int> u;
//只遍历元音字符,返回beg和end之间的数字个数是否为偶数
bool binaryFind(int beg,int end,vector<int> tmp){
//就没有这个字符.直接返回true.
if(tmp.size()==0) return true;
//tmp中存在这个字符。
int len=tmp.size();
int fir_beg; //第一个大于等于beg的位置下标
int fir_end; //最后一个小于等于end的位置下标
//寻找的最开始位置就大于这个字符的最后一个所在位置
if(beg>tmp[len-1]) return true;
//寻找的最后一个位置还小于这个字符出现的第一个位置
if(end<tmp[0]) return true;
//应该寻找fir_beg和fir_end之间相差的元素个数,而不是直接相减.
for(int i=0;i<len;i++){
if(tmp[i]>=beg) {
fir_beg=i;
break;
}
}
if(end>tmp[len-1]) fir_end=len-1;
else {
for(int i=fir_beg;i<len;i++){
if(tmp[i]>end){
fir_end=i-1;
break;
}
}
}
return ((fir_end-fir_beg+1)%2==0);
}
//在beg 和 end当中判断元音字符是否出现了偶数次.
bool find(int beg,int end){
//其实就是判断各个vector中介于beg和end中的数字是否为偶数个.
return (binaryFind(beg,end,a)&&binaryFind(beg,end,e)&&binaryFind(beg,end,i)&&binaryFind(beg,end,o)&&binaryFind(beg,end,u));
}
int findTheLongestSubstring(string s) {
if(s.length()==0){
return 0;
}
for(int j=0;j<s.length();j++){
switch(s[j]){
case 'a':a.push_back(j);break;
case 'e':e.push_back(j);break;
case 'i':i.push_back(j);break;
case 'o':o.push_back(j);break;
case 'u':u.push_back(j);break;
}
}
int i=0;
int length=s.length()-1;
//每次循环 是一个滑动窗口.
while(length>=0){
//窗口的开始是begin,结束是end
for(int i=0;i+length<s.length();i++){
//findchar表示该字符串是否满足元音字母都出现了偶数次.
if(find(i,i+length))
//返回end-begin+1 (i+length-i+1)
return length+1;
}
length--;
}
return 0;
}
};