import java.util.*;
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
//前缀和+HashMap优化的方法
int odd=0;//存储奇数的个数 ,前缀和
int ret=0;//存储最终结果
int arr[]=new int[nums.length+1];//arr[i]表示前缀和为i的次数
arr[0]=1;//表示不选任何数的话,前缀和就为0,所以前缀和为0的一定有一个
for(int i=0;i<nums.length;i++){
odd+=nums[i]&1;
arr[odd]++;
if(odd-k>=0){
ret+=arr[odd-k];
}
}
return ret;
/* 计算的方法
int ret=0;
if(nums.length==0) return 0;
ArrayList<Integer> list=new ArrayList<>();
for(int i=0;i<nums.length;i++){
if((nums[i]&1)==1)
list.add(i);
}
if(list.size()<k) return 0;
for(int i=0;i<list.size();i++){
int left=1;
int right=1;
if(i-1<0) left=list.get(i)+1;
else left=list.get(i)-list.get(i-1);
boolean flag=false;
if(i+k>=list.size()){
right=nums.length-list.get(i+k-1);
flag=true;
}else{
right=list.get(i+k)-list.get(i+k-1);
}
if(i+k-1<list.size())
ret+=left*right;
if (flag) break;
}
return ret;*/
}
}
1371. 每个元音包含偶数次的最长子字符串
过程:考虑使用前缀和计算前面的字符串的奇偶数量。
public int findTheLongestSubstring(String s) {
char[] c=s.toCharArray();
int arr[]=new int[32]; //31=(11111)2 key是状态 value是最小下标
//保存的是 c[i+1]之前(不包括i+1)的奇偶数状态
for(int i=0;i<arr.length;i++){
arr[i]=-1;
}
int ret=0;
arr[0]=0;//状态00000的下标是-1+1=0
int status=0;//原始状态
for(int i=0;i<c.length;i++){
//计算此时的10110(aeiou) 状态 ,0表示偶数,1表示奇数
switch(c[i]){
case('a'):
status=status^(1<<4);//异或相同为0,不同为1;如果原来位置为1,1^1为0,表示由奇数变为偶数
break;
case('e'):
status=status^(1<<3);
break;
case('i'):
status=status^(1<<2);
break;
case('o'):
status=status^(1<<1);
break;
case('u'):
status=status^(1);
break;
default:
break;
}
if(arr[status]==-1){//如果原来位置没有值
arr[status]=i+1;
}else{//如果有,则找到出现偶数次
ret=Math.max(ret, i+1-arr[status]);
}
}
return ret;
}