問題描述:
給你一個字符串 s
,請你返回滿足以下條件的最長子字符串的長度:每個元音字母,即 'a','e','i','o','u' ,在子字符串中都恰好出現了偶數次。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts
示例 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 次。
解題思路:
使用二進制來代替五個元音字母。
0x00001 :a
0x00010 : e
0x00100 : i
0x01000 : o
0x10000 : u
aeiou每個元音用一個bit一共5個bit,32種奇偶次數組合狀態,比如10101可以表示aiu出現奇數次數
oe則出現偶數次數,每當遍歷一個字符,就可以改變當前的aeiou出現的奇偶次數,也即是改變狀態
使用state記錄狀態,遇到元音字母,則將state和其相應的二進制進行異或操作,記錄每次出現的state
當state重複出現時,假設第一次出現在i處第二次出現在j處,那麼i+1-j之間的字符串肯定是滿足aeiou出現均爲偶數次數的
因爲只有經歷了偶數個aeiou,才能回到之前的狀態,爲了使得合理的字符串最長
那麼第一次出現此狀態時,就需要記錄到下標,然後下次遇到相同狀態,計算最大長度
class Solution {
public:
int findTheLongestSubstring(string s) {
map<int,int> stateindex;
int state = 0;
stateindex[0] = -1;
int res = 0;
for(int i=0;i<s.size();i++){
if(s[i]=='a') state = state^0x00001;
if(s[i]=='e') state = state^0x00010;
if(s[i]=='i') state = state^0x00100;
if(s[i]=='o') state = state^0x01000;
if(s[i]=='u') state = state^0x10000;
if(stateindex.count(state)) res = max(res,i-stateindex[state]);
else stateindex[state] = i;
}
return res;
}
};