每日一题算法:2020.5.20每个元音包含偶数次的最长子字符串

这道题要求在给定的字符串中找到一个子字符串,使得a、e、i、o、u这五个元音字母出现的次数都是偶数。可以通过维护一个状态数组,用二进制表示每个元音的状态,然后存储每个状态的起始和结束位置。最后找出状态相同且距离最远的两个位置,确定最长子字符串。但实际实现过程中遇到了错误,需要进一步分析和修正。
摘要由CSDN通过智能技术生成

2020.5.20每个元音包含偶数次的最长子字符串

在这里插入图片描述

默认格式:

class Solution {
   
    public int findTheLongestSubstring(String s) {
   
        
    }
}

解题思路:

这道题的题目略长,理解起来也比较费劲,大致的意思就是要在给的字符串中找出一个字符串,这个字符串中的a,e,i,o,u五个字母都出现了偶数次。

这道题其实和之前写的乘积最大的子数组,和为k的子数组都有一些类似的东西,就是在数组中找一个子数组,如果是数字的话应该是找一个公式,如果是字符串的话就没有办法了,只能找规律。

那就思考一下,有什么规律在其中呢?

首先,字母只有两种状态,前面的是奇数个,前面的是偶数个,那么我们可以记下0-每个字母前面的元音字母个数

比如下面一个字符串

leetcodeisgreat

我们在00000处记下0 表示全都是偶数的起点是0

然后l处不计算,因为他是奇数,对结果是没有影响的

然后在e处记录01000 2表示只有e为奇数的情况是在下标为2的地方为起点

然后又是一个e记下00000 3表示此处是前面所有都是偶数,这里的3代表的是终点

然后t、c直接跳过,遇到o :00010 6

e:01010 8

i:01110 9

a:11110 14

然后在这个数组里找到相同的两个离得最远的,那就是00000 0和00000 3 此时就可以得到最长的串就是0-3,但是要加上辅音的部分,所以从0开始往前找,同时从3开始往右找,找到第一个辅音字母为止。那就是找到o之前,也就是找到了4的位置,此时得到长度就是4

想法是有了,接下来如何实现,为了能够通过状态找到与其想对应的位置,那么应该使用map来存,而要存五个状态很明显是不可能的,所以,很明显,为什么我上面用了1和0来表示,因为我决定用数字来表示状态,状态一共有2^5种,然后在其中存入两个数字,一个是起始位置,一个是结尾位置,在遍历完字符串之后,我们就得到了所有可能的组合的起始位置和结束位置

然后我们遍历这个集合,计算起始位置和结束位置的差最大的那一个

得到那一个状态的起始位置和结束位置,然后分别向前和向后测试,找到第一个元音字母为止,这样就找到了最大的大小。

实现部分:(答案错误)

在这里插入图片描述

说实话,这种算法解得真的不好,除了锻炼一下逻辑思维能力几乎就没用了,自己找的规律漏洞百出,在提交失败之后修改,改出来又是错的,改来改去发现已经不知道哪里有错了。

不过我一定会回来修改的,找到问题在哪,今天就先把他提交了把

class Solution {
   
public int findTheLongestSubstring(String s) {
   

        //做一个map来装数据
        HashMap<Integer,int[]> map=new HashMap<Integer,int[]>();
        char[] chars=s.toCharArray();
        int status=0;
        //第一个的位置是0,0,好理解
        map.put(0,new int[2] );
        int length=0;
        int st=0;
        //开始遍历数组,里面的判断会比较麻烦,在遍历的时候记住间隔,间隔大的设为长度
        for (int i=0;i<chars.length;i++){
   

            //这里如何减少判断的次数?用else if可以在遇到第一个符合的时候跳出判断
            if(chars[i]=='a')
            {
   
                //异或运算,修改状态
                st=0;
                status=status^16;
                //看一下这个状态出现过没有,如果没有出现过,将该地址设置为他的起始地址
                if (map.get(status)==null){
   

                    //状态码的信息,i+1是字母的起始位置,-1是末尾位置的初值,如果最后计算时还是-1表示该状态没有出现过第二次,
                    // 不过实际应该用不到,找后面减前面的最小值,正常最小值是0,而后面如果是-1的话,最小值会小于0,这就意味
                    //着他的长度永远不会是最长的,所以不用计算
                    int[] array={
   i+1,-1};
                    map.put(status, array);
                }
                else
                    //直接改内容是可以改掉的
                    map.get(status)[1]=i+1;
            }
            else if(chars[i]=='e'){
   

                st=0;
                status=status
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值