题目链接
https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/
题目描述
给你一个字符串 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 只包含小写英文字母。
解题思路
看到子串问题,第一反应滑动窗口,试了一天的滑动窗口结果发现本题不适合使用滑动窗口,因为题目有基数偶数的要求,这一要求使得我们无法对滑动窗口进行收缩操作。
1.暴力求解
两种不同双重for循环进行求解。
第一种双重for循环(平常使用较多)
1 for(int i = 0; i < s.size(); i++) 2 for(int j = i; j < s.size(); j++)
第二种双重for循环
1 for(int i = 0; i < s.size(); i++) 2 for(int j = 0; j < i; j++)
2.前缀和+哈希表+利用位运算达到状态压缩的效果
AC代码
1.暴力枚举(以eleete为例子理解)
1 class Solution { 2 public: 3 bool validSub(vector<int>& alp) 4 { 5 return alp['a'-'a']%2==0&&alp['e'-'a']%2==0&&alp['i'-'a']%2==0&& 6 alp['o'-'a']%2==0&&alp['u'-'a']%2==0; 7 } 8 int findTheLongestSubstring(string s) { 9 vector<int> alp(26,0); 10 int result=0; 11 for(int i=0;ii) //采用第二种双重for循环,刚好不超时;如果采用第一种双重for循环则会超时。 12 { 13 ++alp[s[i]-'a']; 14 vector<int> t=alp; 15 for(int j=0;j<=i;++j) 16 { 17 if(i-j+1<=result) 18 { 19 break; 20 } 21 if(validSub(t)) 22 { 23 result=max(result,i-j+1); 24 } 25 --t[s[j]-'a']; 26 } 27 } 28 return result; 29 } 30 };
2.前缀和+哈希表+利用位运算达到状态压缩的效果(以iiid为例理解)
1 class Solution { 2 public: 3 int findTheLongestSubstring(string s) { 4 int ans = 0, status = 0, n = s.size(); 5 vector<int> pos(32, -1); //用数组替代哈希表 6 pos[0] = 0; 7 for (int i = 0; i < n; i ++) { 8 if (s[i] == 'a') { 9 status ^= 1<<0; //^= 异或运算;1<<0:位运算,表示将1的二进制00001左移0位。 10 } else if (s[i] == 'e') { 11 status ^= 1<<1; //1<<1:位运算,表示将1的二进制00001左移1位变为:00010 12 } else if (s[i] == 'i') { 13 status ^= 1<<2; 14 } else if (s[i] == 'o') { 15 status ^= 1<<3; 16 } else if (s[i] == 'u') { 17 status ^= 1<<4; 18 } 19 if (pos[status] != -1) { 20 ans = max(ans, i + 1 - pos[status]); 21 } else { 22 pos[status] = i + 1; 23 } 24 } 25 return ans; 26 } 27 };
使用异或运算快速解决问题:
Leetcode 1371
Leetcode 找出数组中唯一一个没有重复的元素,其他元素都重复出现偶数次。