此题非常精妙。咋看之下,由于计算最长子字符串需要用到字符串之前的状态,所以首先考虑到使用动态规划。
使用动态规划的难点在于如何判断使用dp数组中一个位置元素。这涉及到5个字符的奇偶的判断,参考(chaoxi)了大佬的解法后,可以使用bitmask来解决。利用二进制来表示元音字母出现的奇偶次数,1代表奇数,0代表偶数,由于有5个字母,所以一共需要一个长度为2^5-1数组即可实现状态记录。
class Solution {
public int findTheLongestSubstring(String s) {
int[] pos = new int[1 << 5];
Arrays.fill(pos, -1);
int size = s.length();
int state = 0;
int res = 0;
pos[0] = 0;
for(int i=0; i<size; i++){
switch(s.charAt(i)){
case 'a' : state ^= (1 << 0);break;
case 'e' : state ^= (1 << 1);break;
case 'i' : state ^= (1 << 2);break;
case 'o' : state ^= (1 << 3);break;
case 'u' : state ^= (1 << 4);break;
default: break;
}
if(pos[state] >= 0){
res = Math.max(res, i-pos[state]+1);
}else{
pos[state] = i+1;
}
}
return res;
}
}