难度中等191收藏分享切换为英文关注反馈
给你一个字符串 s
,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 'a','e','i','o','u' ,在子字符串中都恰好出现了偶数次。
示例 1:
输入:s = "eleetminicoworoep" 输出:13 解释:最长子字符串是 "leetminicowor" ,它包含 e,i,o 各 2 个,以及 0 个 a,u 。
示例 2:
输入:s = "leetcodeisgreat" 输出:5 解释:最长子字符串是 "leetc" ,其中包含 2 个 e 。
示例 3:
输入:s = "bcbcbc" 输出:6 解释:这个示例中,字符串 "bcbcbc" 本身就是最长的,因为所有的元音 a,e,i,o,u 都出现了 0 次。
提示:
1 <= s.length <= 5 x 10^5
s
只包含小写英文字母。
以我的智商,只能想到遍历
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int findTheLongestSubstring(string s) {
int i, j, k;
int len = s.size();
int maxlen = 0;
int counta;
int counte;
int counti;
int counto;
int countu;
int jj, ii, aa;
for(i = 0; i < len; i++){
for(j = i; j < len; j++){
counta = 0;
counte = 0;
counti = 0;
counto = 0;
countu = 0;
for(k = i; k <= j; k++){
if(s[k] == 'a'){
counta++;
}
if(s[k] == 'e'){
counte++;
}
if(s[k] == 'i'){
counti++;
}
if(s[k] == 'o'){
counto++;
}
if(s[k] == 'u'){
countu++;
}
}
if((counta % 2 == 0) and (counte % 2 == 0) and (counti % 2 == 0) and (counto % 2 == 0) and (countu % 2 == 0)){
if(j - i + 1 > maxlen){
maxlen = j - i + 1;
jj = j;
ii = i;
aa = counta;
}
}
}
}
cout << maxlen << endl;
return maxlen;
}
int main(){
string s = "id";
findTheLongestSubstring(s);
return 0;
}
果然不出我所料,超时了
借鉴了大佬,果然智慧,用到了哈希表和状态压缩
听着好像一脸懵,其实哈希表你就想是一个一对一的字典,找起来更快一些
而状态压缩就是换了一种判断的方式
#include <iostream>
#include <cstdio>
#include <cstring>
#include<unordered_map>
using namespace std;
int findTheLongestSubstring(string s) {
// aeiou每个元音用一个bit一共5个bit,共有32种奇偶次数组合状态,比如10101可以表示aiu出现奇数次数
// oe则出现偶数次数,每当遍历一个字符,就可以改变当前的aeiou出现的奇偶次数,也即是改变状态
// 显然,如果两次出现了同样的状态,假设第一次出现在i处
// 第二次出现在j处,那么i+1-j之间的字符串肯定是满足aeiou出现均为偶数次数的
// 因为每一位只有经历偶数次变化才能变回原样
// 为了使得合理的字符串最长
// 那么第一次出现此状态时,就需要记录到下标,然后下次遇到相同状态,计算最大长度
unordered_map<int, int> stateToIndex;
int state = 0x0;
// 初始化,刚开始时,state的状态已经是0x00000,已经出现,因此必须记录
stateToIndex[state] = -1;
// a e i o u 分别在第12345个bit,来表示出现次数的奇偶性
int maxlen = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'a') state ^= 0x00001;
if (s[i] == 'e') state ^= 0x00010;
if (s[i] == 'i') state ^= 0x00100;
if (s[i] == 'o') state ^= 0x01000;
if (s[i] == 'u') state ^= 0x10000;
if (stateToIndex.count(state)) maxlen = max(maxlen, i - stateToIndex[state]);
else stateToIndex[state] = i;
}
cout << maxlen << endl;
return maxlen;
}
int main(){
string s = "id";
findTheLongestSubstring(s);
return 0;
}
解释我写在了代码中
希望对你有帮助