# 每个元音包含偶数次的最长子字符串
给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 'a','e','i','o','u' ,在子字符串中都恰好出现了偶数次。
示例 1:
输入:s = "eleetminicoworoep"
输出:13
解释:最长子字符串是 "leetminicowor" ,它包含 e,i,o 各 2 个,以及 0 个 a,u 。
示例 2:
1
2
3
4
2
3
4
输入:s = "leetcodeisgreat"
输出:5
解释:最长子字符串是 "leetc" ,其中包含 2 个 e 。
示例 3:
1
2
3
4
2
3
4
输入:s = "bcbcbc"
输出:6
解释:这个示例中,字符串 "bcbcbc" 本身就是最长的,因为所有的元音 a,e,i,o,u 都出现了 0 次。
1
2
3
2
3
提示:
1 <= s.length <= 5 x 10^5
s 只包含小写英文字母。
1
2
2
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts
此题思考了下无思路果断去看了题解,主要思路就是前缀和,状态压缩
首先前缀和的思想,什么情况下用前缀和,当涉及到某区间是否满足某条件时,可通过区间边界的前缀和来判断出是否满足条件的;
示例:
pre[i]: 0 到 i 位置的奇偶情况
pre[m]-pre[k] = 0 m位置的奇偶情况与n位置的奇偶情况一致,就表示[m,k]
奇偶情况
需要特别注意在为pre[i]=0的时候,说明0-i满足偶数条件,可直接计算长度为i+1
/**
* @param {string} s
* @return {number}
*/
var findTheLongestSubstring = function(s) {
let vowelList = {
'a':1,'e':2,'i':4,'o':8,'u':16
}
let pre = [vowelList[s.charAt(0)]||0]
let map = {}
map[pre[0]] = 0
let length = 0
for(let i=1;i<s.length;i++){
let vNum = vowelList[s.charAt(i)]||0
pre[i] = pre[i-1] ^ vNum
if(pre[i]!=0){//
if(map[pre[i]]===undefined){
map[pre[i]] = i
}else{
length = Math.max(length,i-map[pre[i]])
}
}else{//为0的时候,说明与前面到现在都为偶数
length = Math.max(length,i+1)
}
}
return length
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28