提示
1 <= s.length <= 10^5
s
由小写英文字母组成1 <= k <= s.length
思路
- 如果
k
的长度大于等于s
的长度,遍历s
并统计元音数目,遍历完毕直接返回结果值 - 如果
k
的长度小于s
的长度,即定长的滑动窗口
问题,用ans
动态更新最大元音字符数,窗口向右滑动过程,细节如下:- 判断滑动前的左端点是否为元音字符
- 滑动后的右端点是否为元音字符
代码
/*
*12ms
*/
public int maxVowels(String s, int k) {
int ans=0;
if(k>=s.length()){
for(char c:s.toCharArray()){
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){
ans++;
}
}
return ans;
}else{
int len=0;
//预处理
for(int i=0;i<k;i++){
char c=s.charAt(i);
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){
len++;
}
}
ans=len;
for(int left=1,end=k;end<s.length();end++, left++){
char preLeft=s.charAt(left-1);
char c=s.charAt(end);
if(preLeft=='a'||preLeft=='e'||preLeft=='i'||preLeft=='o'||preLeft=='u'){
len--;
}
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){
len++;
}
ans=Math.max(ans, len);
}
return ans;
}
}
优化
- 整理 窗口移动 过程代码
/*
* 12ms
*/
public int maxVoAnInt3(String s,int k){
int n=s.length(),ans=0,count=0;
for(int i=0,j=0;j<n;j++){
//右指针
char c=s.charAt(j);
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){
count++;
}
//当长度大于k时,左指针开始移动
if(j>k-1){
//左指针
char c1=s.charAt(i);
if(c1=='a'||c1=='e'||c1=='i'||c1=='o'||c1=='u'){
count--;
}
i++;
}
ans=Math.max(ans, count);
}
return ans;
}
以上优化是参考以下代码,原文:Alex:Java双指针滑动窗口
/**
* 以"aeiou"为参照
* 22ms
*/
public int maxVowAnInt2(String s,int k){
int n=s.length();
int count=0,ans=0;
int i=0;
for(int j=0;j<n;j++){
if("aeiou".indexOf(s.charAt(j))!=-1)count++;
if(j>k-1){
if("aeiou".indexOf(s.charAt(i))!=-1) count--;
i++;
}
ans=Math.max(ans, count);
}
return ans;
}