【LeetCode】1371. 每个元音包含偶数次的最长子字符串

题目链接

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;i<s.size();++i) //采用第二种双重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 找出数组中唯一一个没有重复的元素,其他元素都重复出现偶数次。

 

posted @ 2020-05-21 12:02  控球强迫症  阅读(438)  评论(0编辑  收藏  举报