LeetCode 1371. 每个元音包含偶数次的最长子字符串

https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/

这个是今天的每日一题,菜鸡的我又没有作出来 QAQ

只能乖乖去看花花酱的视频了,贴一下代码吧

public int findTheLongestSubstring(String s) {
        char[] vol = new char[]{'a','e','i','o','u'};
        int[] list = new int[32];
        Arrays.fill(list,Integer.MAX_VALUE);
        list[0] = -1;
        int max = 0;
        int state = 0;
        for(int i = 0;i < s.length(); i++){
            for(int j = 0; j < vol.length; j++){
                if(s.charAt(i) == vol[j]){
                    state ^= 1<<j;
                }
            }
            if(list[state] == Integer.MAX_VALUE){
                list[state] = i;
            }
            max = Math.max(max,i-list[state]);
        }
        return max;
    }

这个题考的知识点真的好多好多,首先有前缀和,类似15号的每日一题LeetCode 560,还有就是状态压缩,类似于老鼠检验毒药问要多少只老鼠的题目。

首先我们用一个char数组记录下元音字母。另外我们需要一个32位的数组来记录每个状态的第一次出现的位置,因为状态压缩后,一共有5位二进制位,2^5=32.

首先我们将第一个状态位置-1,因为全部的元音为偶数情况有可能是整个字符串。

然后看循环,第一层循环是遍历整个字符串,因为这个字符串规模很大,最多只支持我们遍历一次。

第二层循环是判断当前字符是否为其中的一个元音,如果是的话就将状态位与1<<j,即00000中的第j位被置为1,然后再与state进行异或,将状态进行转换。

然后如果当前状态的第一次出现的位置为Integer.MAX_VALUE的话,就表示这个状态从来没出现过,这里是第一次出现,将i赋予它。

然后就是比较max和i-list[state]这个哪个更长,记录下来最长的那个即可。

这里贴一下花花酱的视频,可能比我这个讲解会更好理解。https://www.bilibili.com/video/BV1CE411K7hb

原文地址:https://www.cnblogs.com/ZJPaang/p/12922433.html