Leetcode——剑指offer3. 无重复字符的最长子串

在这里插入图片描述
方法一二判断相等的方法还是空间换时间,维护一个长度128的flag的bool数组(涵盖ascll表),访问一次数组元素置true,二次访问则说明有重复元素。

方法一:
暴力
时间复杂度O(n^3)
最长的测试用例超时

class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        int length=s.size();
        bool re=true;
        for(int i=length;i>=2;i--)
        {
            for(int j=0;j<=length-i;j++)
            {
                re=true;
                bool flag[26]={false};
                int temp;
                for(int k=j;k<j+i;k++)
                {
                    temp=int(s[k])-97;
                    if(flag[temp]==true)
                    {
                        re=false;
                        break;
                    }
                    else
                    {
                        flag[temp]=true;
                    }
                }
                if(re)
                {
                    return i;
                }
            }
        }
        return 1;
    }
};

方法二:
扫描,时间复杂度O(n^2),可以过全部用例,但是还是比较慢,不满意。
大体思路:从头开始扫描,遇到重复字符就将初始的位置+1,后来想优化一下,类似kmp的思路,就是维护一个二维数组,【x】【0】记录是否访问,【x】【1】记录位置,以后x元素重复了可以直接从【x】【1】开始再找,相当于多向前走了几步,而不是一步一步走。按理来说,这样写时间复杂度是O(n),但是可能访问二维数组比一维数组慢,不但没有变快反而变慢了。都把代码贴出来。
原始版

class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        int length=s.size();
        if(length==0)
        {
            return 0;
        }
        int re=1;
        int temp;
        int dis=0;
        for(int i=0;i<length;i=i+1)
        {
            bool flag[128]={false};
            dis=0;
            for(int j=i;j<length;j++)
            {
                temp=int(s[j]);
                if(flag[temp]==true)
                {
                    break;
                }
                else
                {
                    flag[temp]=true;
                }
                dis++;
            }
            if(dis>re)
            {
                re=dis;
            }
        }
        return re;
    }
};

“优化版”


class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        int length=s.size();
        if(length==0)
        {
            return 0;
        }
        int re=1;
        int temp;
        int dis=0;
        int a=0;
        int ahead=0;
//        string str="pwwkew";
        for(int i=0;i<length;i=ahead)
        {
            int flag[128][2]={0};
            ahead=i+1;
            dis=0;
            for(int j=i;j<length;j++)
            {
                temp=int(s[j]);
                if(flag[temp][0]==1)
                {
                    ahead=flag[temp][1]+1;
                    break;
                }
                else
                {
                    flag[temp][0]=1;
                    flag[temp][1]=j;
                }
                dis++;
            }
            if(dis>re)
            {
                re=dis;
            }
        }
        return re;
    }
};

方法三:
滑动窗口

class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        int ssize=s.size();
        if(ssize==0)
            return 0;
        int start(0),re(0),length(0);
        char temp;
        for(int i=0;i<ssize;i++)
        {
            temp=s[i];
            length=i-start;
            for(int j=start;j<i;j++)
            {
                if(s[j]==temp)
                {
                    start=j+1;
                    length=i-start;
                }
            }
            length++;
            if(length>re)
            {
                re=length;
            }
        }
        return re;
    }
};

方法四
哈希存储出现重复的字符最后一次出现的位置。和我方法二中企图用二维数组实现一个思路,但是hash快多了。复杂度 O(n)

class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        //s[start,end) 前面包含 后面不包含
        int start(0), end(0), length(0), result(0);
        int sSize = int(s.size());
        unordered_map<char, int> hash;
        while (end < sSize)
        {
            char tmpChar = s[end];
            //仅当s[start,end) 中存在s[end]时更新start
            if (hash.find(tmpChar) != hash.end() && hash[tmpChar] >= start)
            {
                start = hash[tmpChar] + 1;
                length = end - start;
            }
            hash[tmpChar] = end;

            end++;
            length++;
            result = max(result, length);
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值