LeetCode 3无重复字符的最长子串

原题链接

1

单纯的每一遍以第i个元素为基准,每次逆序找到与s[i]相等的第一个元素的下标,pwwkew就过不了,预期为3,我的结果为5,看到结果,就知道没考虑中间的重复,接着第二个程序引入flag记录最近的重复字符的一对字符中下标小的字符的下标;

int lengthOfLongestSubstring(char* s) {
    int len=strlen(s);int max=0,now=0;int flag=0;
    /*for(int i=0;s[i]!='\0';i++)
    {
        len++;
    }*/
    for(int i=0;i<len;i++)
    {
        now=1;
        for(int j=i-1;j>=flag;j--)
        {
            if(s[j]==s[i])
            {
                flag=j+1;
                break;
            }
            now++;
        }
        if(now>max)
        {
            max=now;
        }
    }
    return max;
}

2

虽然过了,但结果不理想,复杂度还是n^2,有点低效;想看看Dior一点的人怎么写的;打开参考代码,看到map[256];就想到哈希表了;就自己写去了;也没看懂256什么意思;就有了3

int lengthOfLongestSubstring(char* s) {
    int len=strlen(s);int max=0;int flag=0;//now可以由i-flag+1得到,其实对时空复杂度也没起到多大影响,节省了一点空间,时间也上去了,没什么用;
    for(int i=0;i<len;i++)
    {
        for(int j=i-1;j>=flag;j--)
        {
            if(s[j]==s[i])
            {
                flag=j+1;
                break;
            }
        }
        if(i-flag+1>max)
        {
            max=i-flag+1;
        }
    }
    return max;
}

3

从示例代码中只有小写字母;就造了26的哈希;哈希表用来存上一个本字符的下标;结果先在一堆各种字符中死掉了;map更新写错了也忘写flag了,接着有了4

int lengthOfLongestSubstring(char* s) {
    int len=strlen(s);
    int map[26];
    for(int i=0;i<26;i++)
    {
        map[i]=-1;
    }
    int max=0,now=0;
    for(int i=0;i<len;i++)
    {
        if(map[s[i]-'a']==-1)
        {
            map[s[i]-'a']=i;
        }
        else
        {
            now=i-map[s[i]-'a'];
        }
        if(now>max)
        {
            max=now;
        }
    }
    return max;
}

4

int lengthOfLongestSubstring(char* s) {
    int len=strlen(s);//s长
    if(len==0)//特殊处理,提高效率
    {
        return 0;
    }
    int map[256];
    for(int i=0;i<256;i++)
    {
        map[i]=-1;
    }//初始化,可以不要0号;\0没机会被判断;
    int max=0,now=0;//now表示以当前字符结束的串的长度
    int flag=0;//这里是错的
    for(int i=0;i<len;i++)
    {
        if(map[s[i]-'\0']==-1)
        {
            ;
        }
        else
        {
            flag=(flag>map[s[i]-'\0']?flag:map[s[i]-'\0']);//更新flag,取大的;
        }
        now=i-flag;//长度
        map[s[i]-'\0']=i;//更新,先用再更新;
        if(now>max)
        {
            max=now;
        }
    }
    return max;
}

5

上面的代码虽然可以过一部分示例,但是错的地方很多;flag应该为-1,若为0,则表示意义与原意不符,且没重复字符时now会少算1;而且三目运算符慢于if else组合;原因是三目运算符会引入中间变量;参考博客

int lengthOfLongestSubstring(char* s) {
    int len=strlen(s);
    if(len==0)
    {
        return 0;
    }
    int map[256];
    for(int i=0;i<256;i++)
    {
        map[i]=-1;
    }
    int max=0,now=0;
    int flag=-1;
    for(int i=0;i<len;i++)
    {
        if(map[s[i]]==-1)
        {
            ;
        }
        else
        {
            if(flag<map[s[i]])
            {
                flag=map[s[i]];
            }
            //flag=(flag>map[s[i]]?flag:map[s[i]]);
        }
        now=i-flag;
        map[s[i]]=i;
        if(now>max)
        {
            max=now;
        }
    }
    return max;
}

接着就有高rank比了,顺便说一句LeetCode上每次提交时间波动有点大,多试几次也可以刷高一点rank比,但最重要的还是算法的优秀程度;

学习与思考

  1. 哈希表能实现类似记忆的效果;在解决字符问题中很常用;
  2. if else 比三目快;
  3. 关键在于falg;

猜你喜欢

转载自blog.csdn.net/m0_38062488/article/details/80706906