Leetcode 3.Longest Substring Without Repeating Characters(hashmap)

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for “abcabcbb” is “abc”, which the length is 3. For “bbbbb” the longest substring is “b”, with the length of 1.

Difficulty:Medium

分析:这道题看完后就觉得应该是将字符进行一个一一映射,本来是想着以字母’a’为基准的话,可以映射到一个唯一的数字,这样用一个数组维护,但是不知道数组开多大,同时一碰到这种映射的关系,马上就想到了hash表,所以就先换了一种hashmap的方法。但是一开始想的这个方法使用两个循环,找到子串后,将寻找子串的基准只往后移动一位,复杂度 O(n2) ,这种算法最终超时了。

class Solution {
public:
    int lengthOfLongestSubstring(string s) 
    {
        int len=s.length();
        if(len<2)
            return len;
        unordered_map<char,int>hashmap;
        int maxSubLen=0;
        for(int i=0;i<len;i++)
        {
            if(maxSubLen>=len-i)//后续字符串长度小于找到的最大字串长度
                break;
            int curSubLen=0;
            //pair<unordered_map<char,int>::iterator,bool>ret;
            for(int j=i;j<len;j++)
            {
                if(!(hashmap.insert({s[j],++curSubLen})).second)
                {
                    curSubLen--;
                    hashmap.clear();
                    break;
                }
            }
            maxSubLen=curSubLen>maxSubLen?curSubLen:maxSubLen;
        }
        return maxSubLen;
    }
};

后来分析了一下,其实当找到一个不重复的子串后,后面出现的字母一定在前面子串的某一位中,这样子串中那个字母以前的字符其实都不用考虑了,这样可以简化循环。

    int lengthOfLongestSubstring(string s) 
    {
        int len=s.length();
        if(len<2)
            return len;
        unordered_map<char,int>hashmap;
        int maxSubLen=0;
        int curSubLen=0;
        int index=0;
        for(int i=0;i<len;i++)
        {
            if((hashmap.insert({s[i],i})).second)
                curSubLen++;
            else
            {
                maxSubLen=curSubLen>maxSubLen?curSubLen:maxSubLen;
                int pos=hashmap[s[i]];
                int dis=pos-index;
                for(int j=index;j<=pos;j++)
                    hashmap.erase(s[j]);
                curSubLen-=dis;
                index=pos+1;
                hashmap.insert({s[i],i});
            }
        }
        return curSubLen>maxSubLen?curSubLen:maxSubLen;
    }*/

这种方法最终能通过测试,但是耗时76ms,我感觉还是时间太慢。一方面还是用了二层循环,另一方面感觉hash的添加和删除可能还是耗时。后来就又参考了一下别人的思路,最终用数组的方式来实现,只需要修改数组的值就行,不需要添加和删除操作,最终速度是16ms。

    int lengthOfLongestSubstring(string s)
    {
        int dict[256]={0};
        int len=s.length();
        int maxSubLen=0,curSubLen=0,index=1;
        for(int i=0;i<len;i++)
        {
            int curIndex=dict[s[i]];
            if((!curIndex)||(curIndex<index))
                curSubLen++;
            else
            {
                maxSubLen=curSubLen>maxSubLen?curSubLen:maxSubLen;
                curSubLen-=(curIndex-index);
                index=curIndex+1;
            }
            dict[s[i]]=i+1;
        }
        return curSubLen>maxSubLen?curSubLen:maxSubLen;
    }

猜你喜欢

转载自blog.csdn.net/u012462822/article/details/50896688