这道题我自己是想不出来的,看了官方答案之后,太妙了,其中也包含了一个我没有接触过的算法——“前缀和”算法。
题解:前缀和+状态压缩
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 }
浙公网安备 33010602011771号