这道题我自己是想不出来的,看了官方答案之后,太妙了,其中也包含了一个我没有接触过的算法——“前缀和”算法。

题解:前缀和+状态压缩

1. 首先要考虑的事情就是如何记录a e i o u出现的次数是奇数还是偶数,有一个很巧妙的想法就是0代表偶数,1代表奇数,用5位进制数才代表5个元音出现次数的状态;

2. 接下来一个重要的事是记录一个状态出现的最早的位置,即pos[status],以后再出现这个状态时就可以用当前位置减去pos[status],就可以得出符合条件的字符串的长度。因为奇数减奇数是偶数,偶数减偶数也是偶数。

代码:

 1 class Solution {
 2     public int findTheLongestSubstring(String s) {
 3         int status = 0;
 4         int ans = 0;
 5         int[] pos = new int[1 << 5];//长为32的数组
 6         Arrays.fill(pos, -1);
 7         pos[0] = 0; //初始化为0,即最开始aeiou的个数都是0的位置为0,此时的状态为都是偶数
 8         for(int i = 0; i < s.length(); i++){
 9             char ch = s.charAt(i);
10             if(ch == 'a')
11                 status ^= 1 << 4;
12             else if(ch == 'e')
13                 status ^= 1 << 3;
14             else if(ch == 'i')
15                 status ^= 1 << 2;
16             else if(ch == 'o')
17                 status ^= 1 << 1;
18             else if(ch == 'u')
19                 status ^= 1 << 0;
20             if(pos[status] >= 0) //说明这个状态之前出现过
21                 ans = Math.max(ans, i+1-pos[status]);
22             else
23                 pos[status] = i + 1; //记录下出现这个状态的最早的位置
24         }
25         return ans;
26     }
27 }
View Code

 

posted on 2020-05-20 15:27  小小糖果tt  阅读(82)  评论(0)    收藏  举报