LeetCode 3. 无重复字符的最长子串 (超时的问题)

LeetCode 查找无重复字串时间复杂度问题

    今天做到LeetCode的第三题,

    

给定一个字符串,找出不含有重复字符的 最长子串 的长度。

示例:

给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3。

给定 "bbbbb" ,最长的子串就是 "b" ,长度是1。

给定 "pwwkew" ,最长子串是 "wke" ,长度是3。请注意答案必须是一个子串"pwke" 是 子序列 而不是子串。

    万般WA之后

    本以为AC,不知竟然是RE

    看了相关文章之后复杂度太高了 原代码如下复杂度近乎为O(n^2)

class Solution 
{
public:
    int Find(char c,int i,int j,string s);
    int lengthOfLongestSubstring(string s) 
    {
        int MAX  = 0;
        for(int i = 0;i < s.size();i++)
        {
            int number = 1;
            for(int j = i;j < s.size()-1;j++)
            {
                if(Find(s[j+1],i,j,s)==-1) number++;
                else break;
            }
            if(MAX<number) MAX = number;
        }
        return MAX;
    }
};


int Solution::Find(char c,int i,int j,string s)
{
    for(int a = i;a <= j;a++)
    {
        if(c==s[a]) return a;
    }
    return -1;
}

优化后:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int i = 0, j = 0;
        int n = s.length();
        int maxLen = -1;
        bool exists[256] = { false };
 
        while (j < n)
        {
            if (exists[s[j]])
            {
                maxLen = max(maxLen, j - i);
                while (s[i] != s[j])
                {
                    exists[s[i]] = false;
                    i++;
                }
                i++;
            }
            else
            {
                exists[s[j]] = true;
            }
            j++;
        }
        // 考虑"abcd",j遍历完字符串之后,maxLen在while循环中并没有更新,需要在循环外更新一次
        maxLen = max(maxLen, j - i); 
 
        return maxLen;
    }
};

主要思想在于一次遍历

例子“abcdbe"

第一种方法在j遇到b,获得重复信息,所以将i++,j = i;如果重复的是第一个字母,两者一样,但往往并不是这样

所以这是多余的,

第二种在j遇到b时,只变动i = 'c'的位置,而j继续++,复杂度为O(n)

因为如果i只是++,那么必然遇见第二个'b'还是会重新来一遍,这显然是多于的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值