leetcode每日一题(0520) c++——1371.每个元音包含偶数次的最长子字符串

今天是520.祝愿天下的程序员们早日脱单,升职加薪,生活幸福美满 ~

题目描述

在这里插入图片描述

只要求最长的子串长度,所以我第一时间考虑的是滑动窗口,如果该窗口的长度满足之后就直接返回该长度即可。

思路:
暴力解法:从长至短,遍历所有子串,在每个子串中查询各个元音字符出现的次数。这个肯定超时啊,所以想办法优化一下,超时的原因是什么?是因为每次子串的遍历都要进行元音和辅音字符的判断,那能否减少这样的判断呢?当然可以,我们用数组来表示整个字符串当中所有元音字符出现的位置,这样。我们每次在子串中只遍历元音字符即可~

思路有了,代码其实就不难了


//首先想到的是暴力解法.从最长开始解.如果

//双指针i,j指向头尾,如果这个字符串不满足,就判断i++->j的字符串满足与否, 以及i->j--的字符串满足与否
//记录每个元音字符串的位置.
class Solution {
public:


    vector<int> a; //记录a字符出现的在字符串中出现的位置
    vector<int> e;
    vector<int> i;
    vector<int> o;
    vector<int> u;

    //只遍历元音字符,返回beg和end之间的数字个数是否为偶数
    bool binaryFind(int beg,int end,vector<int> tmp){
        //就没有这个字符.直接返回true.
        if(tmp.size()==0) return true;
        //tmp中存在这个字符。
        int len=tmp.size();
        int fir_beg;  //第一个大于等于beg的位置下标
        int fir_end;  //最后一个小于等于end的位置下标
        //寻找的最开始位置就大于这个字符的最后一个所在位置
        if(beg>tmp[len-1]) return true;
        //寻找的最后一个位置还小于这个字符出现的第一个位置
        if(end<tmp[0]) return true;

        //应该寻找fir_beg和fir_end之间相差的元素个数,而不是直接相减.
        for(int i=0;i<len;i++){
            if(tmp[i]>=beg) {
                fir_beg=i;
                break;
            }
        }
        if(end>tmp[len-1]) fir_end=len-1;
        else {
            for(int i=fir_beg;i<len;i++){
                if(tmp[i]>end){
                    fir_end=i-1;
                    break;
                }
             }
        }
        return ((fir_end-fir_beg+1)%2==0);
    }
    //在beg 和 end当中判断元音字符是否出现了偶数次.
    bool find(int beg,int end){
        //其实就是判断各个vector中介于beg和end中的数字是否为偶数个.
        return (binaryFind(beg,end,a)&&binaryFind(beg,end,e)&&binaryFind(beg,end,i)&&binaryFind(beg,end,o)&&binaryFind(beg,end,u));
    }
    int findTheLongestSubstring(string s) {
        if(s.length()==0){
            return 0;
        }
        for(int j=0;j<s.length();j++){
            switch(s[j]){
                case 'a':a.push_back(j);break;
                case 'e':e.push_back(j);break;
                case 'i':i.push_back(j);break;
                case 'o':o.push_back(j);break;
                case 'u':u.push_back(j);break;
            }
        }
        int i=0;
        int length=s.length()-1;
        //每次循环 是一个滑动窗口.
        while(length>=0){
            //窗口的开始是begin,结束是end
            for(int i=0;i+length<s.length();i++){
                //findchar表示该字符串是否满足元音字母都出现了偶数次.
                if(find(i,i+length))
                    //返回end-begin+1 (i+length-i+1)
                    return length+1;
            }
            length--;
        }
        return 0;
        
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值