class Solution:
def findTheLongestSubstring(self, s: str) -> int:
"""tc O(N) sc O(2^M)
use a counter to get # each vowels
if in substring, if vowel = 0, can keep increasing
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
main idea: bit mask. note it's not about counting number of each vowels in string. it's check if vowels is odd or even
e.g. if 'a' is odd, mask 00001, o
update mask as looping each ch in s, track smallest idx for each mask combination
if same mask seen, string between smallest(exclusive) and current (inclusive) index meet criteria
==>
find max dist betwwen first and last index fir each mask comb
"""
seen = {0:-1} # for case where s contains no vowels, longest substring applied is i-(-1) = i + 1
res = mask = 0
d={'a':1,'e':2,'i':4,'o':8,'u':16}
for i,c in enumerate(s):
#mask ^= 1 << ('aeiou'.find(c)+1) >> 1
#idx = 'aeiou'.find(c) # in case find() return -1
idx = d.get(s[i],-1)
if idx != -1:
state = 1 << idx
else:
state = 0
#state = state >> 1
mask = mask ^ state
if mask not in seen:
seen[mask] = i #[!important] record index of first occurance of mask
res = max(res,i-seen[mask]) #string between smallest(exclusive) and current (inclusive) index meet criteria
return res