題目
給你一個字符串 s ,請你返回滿足以下條件的最長子字符串的長度:每個元音字母,即 ‘a’,‘e’,‘i’,‘o’,‘u’ ,在子字符串中都恰好出現了偶數次。
思路
- 如何標識元音所在位置?
(1) 前綴和:使用A[i][k]記錄元音所在位置,其中i爲元音在字符串中的位置,k爲元音的標識(即a,e,i,o,u分別對應k=0,1,2,3,4)。
(2)狀態壓縮:
根據題目要求,不需要知道元音的具體數目,所以可以將前綴和的思路進行簡化——使用二進制位運算標識元音的奇偶數。
例如在第i個位置(a,e,i,o,u)=(1,1,0,1,1)。1表示該位置元音字母爲奇數,0表示該位置元音字母爲偶數。 - 如何計算最長子字符串?
最長子字符串是根據元音位置決定的。可以使用數組標識元音爲奇數所在位置的座標來計算。具體的實現可以從代碼中看出。
代碼
class Solution {
public int findTheLongestSubstring(String s) {
int len = s.length();
//數組存儲有效起始位置
int[] pos = new int[1<<5];
Arrays.fill(pos,-1);
pos[0]=0;
int status=0;
int maxLen=0;
for(int i=0; i<len; i++){
char ch = s.charAt(i);
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);
}
if(pos[status]>=0){
maxLen=Math.max(maxLen,i+1-pos[status]);
}else{
pos[status]=i+1;
}
}
return maxLen;
}
}
算法複雜度
- 時間複雜度:O(n)
- 空間複雜度:O(1) //只使用了常數個空間,pos數組的長度爲32.