難度中等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;
}
解釋我寫在了代碼中
希望對你有幫助