LeetCode1371.每個元音包括偶數次的最長子字符串
題目
分析
錯誤示範:
首先我先想到的思路就是先把整個字符串遍歷一遍,找出所有的元音字母的奇偶數,然後分別從首尾進行遍歷刪除元素爲奇數的元素,但是會造成把原本是偶數對的元音給刪成奇數對。所以不行
正解:
- 首先對於五個元音的處理,因爲每個元音的奇偶數只有兩種狀態,要麼奇要麼偶,所以可以使用01來進行區分,然後一共五位,所以維護一個五位數的二進制數來表示每個元素從頭到現在的五個元音的奇偶個數。其中0表示出現了偶數次數,1表示奇數次數。
- 然後維護一個長度爲32的數組(元音狀態一共有32種),然後每當第一次出現一種新的元音狀態的情況,就把當前的位置記錄到這個數組中,方便後面如果出現這種同樣的元音情況,就可以直接計算出當前位置到第一個位置的長度,即爲一個符合標準的子串。
- 然後更新最大的長度,最後返回即可
代碼實現
public static int findTheLongestSubstring(String s) {
int len=s.length();
// 創建數組,用來記錄這種情況的元音第一次出現的位置
int[] pos=new int[1<<5];
// 先全部置位-1
Arrays.fill(pos,-1);
// ans 記錄暫時最長的子串,status標誌元音情況
int ans=0,status=0;
// 初始0位置的元素
pos[0]=0;
for(int i=0;i<len;i++){
char ch=s.charAt(i);
// 進行遍歷改變state的值
if(ch=='a'){
status^=(1<<0);
}else if(ch=='e'){
status^=(1<<1);
}else if(ch=='i'){
status^=(1<<2);
}else if(ch=='o'){
status^=(1<<3);
}else if(ch=='u'){
status^=(1<<4);
}
// 如果這個元音的值不是-1說明前面有這種情況的元音,就進行一次計算獲得暫時的最大值
if(pos[status]>=0){
ans=Math.max(ans,i-pos[status]+1);
}else {
// 不是的話,說明第一次出現這種情況,將第一次的位置記錄到pos數組中
pos[status]=i+1;
}
}
return ans;
}