zoukankan      html  css  js  c++  java
  • 【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 找出数组中唯一一个没有重复的元素,其他元素都重复出现偶数次。

  • 相关阅读:
    每天一点点之css
    【Vue中的坑】Vue中的修改变量没有效果?
    每天一点点之vue框架开发
    每天一点点之laravel框架开发
    每天一点点之vue框架开发
    推荐几款好用的办公软件
    每天一点点之vue框架开发
    Unity3D调用摄像头,画面为翻转的问题
    正确显示竖屏预览和拍照的照片
    卡尔曼滤波简介+ 算法实现代码
  • 原文地址:https://www.cnblogs.com/XDU-Lakers/p/12927494.html
Copyright © 2011-2022 走看看