1 class Solution {
 2     public int findTheLongestSubstring(String s) {
 3         int n = s.length();
 4         Map<Character, Integer> map = new HashMap<>();
 5         map.put('a', 0);
 6         map.put('e', 0);
 7         map.put('i', 0);
 8         map.put('o', 0);
 9         map.put('u', 0);
10         int l = 0, maxlen = 0;
11         for (int r = 0; r < n; r++) {
12             char curr = s.charAt(r);
13             if (map.containsKey(curr)) {
14                 map.put(curr, map.get(curr) + 1);
15             }
16             Map<Character, Integer> temp = new HashMap<>();
17 
18             temp.put('a', map.get('a'));
19             temp.put('e', map.get('e'));
20             temp.put('i', map.get('i'));
21             temp.put('o', map.get('o'));
22             temp.put('u', map.get('u'));
23 
24             while (temp.get('a') % 2 == 1 || temp.get('e') % 2 == 1 || temp.get('i') % 2 == 1 || temp.get('o') % 2 == 1
25                     || temp.get('u') % 2 == 1) {
26                 char left = s.charAt(l);
27                 if (temp.containsKey(left)) {
28                     temp.put(left, temp.get(left) - 1);
29                 }
30                 l++;
31             }
32             maxlen = Math.max(maxlen, r - l + 1);
33             l = 0;
34         }
35         return maxlen;
36     }
37 }

参考:https://leetcode.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/discuss/532958/Easy-Solution-Using-Sliding-Window-In-Java!

算法思路:滑动窗口。

分析:两层循环,外层确定右边界,内层确定左边界。

每次外层循环,都复制一份元音字母个数的字典放到temp中。判断当前状态是否存在某个元音字符的个数是奇数个。

  如果存在这样的元音字符,则将左边界向右移动,一直到所有元音字符都是偶数个为止。此时找到一种解决方案,跳出循环。

计算此时的字串的长度,并更新最大长度字段maxlen。

可见这种解决方案的时间复杂度是O(n*n),效率比较低。

在leetcode上的执行结果为:

 

 

 

第二种方案:

 1 class Solution {
 2     public int findTheLongestSubstring(String s) {
 3         int res = 0 , cur = 0, n = s.length();
 4         HashMap<Integer, Integer> seen = new HashMap<>();
 5         seen.put(0, -1);
 6         for (int i = 0; i < n; ++i) {
 7             cur ^= 1 << ("aeiou".indexOf(s.charAt(i)) + 1 ) >> 1;
 8             seen.putIfAbsent(cur, i);
 9             res = Math.max(res, i - seen.get(cur));
10         }
11         return res;
12     }
13 }

算法思路:位运算。

分析:这应该是本题的比较好的解决方案。

在leetcode上的执行结果:

 

与第一种方案对比,执行效率高了很多,但不太容易理解。

posted on 2020-03-19 09:50  Sempron2800+  阅读(330)  评论(0编辑  收藏  举报