leetrcode 3 Longest Substring Without Repeating Characters

1 篇文章 0 订阅
0 篇文章 0 订阅

思想:利用hash的方法记录某个字符是否重复出现,空间为256个int,然后逐个探测以每个字符开始出现的最大长度,当第K个字符与前面第i个字符重复时则直接从第i+1个字符开始探测最大长度。此种解法为45ms,看到时间排名比较靠后就去看了别人的解法,发现可以进一步优化:当从第i+1个字符开始探测时可以直接从第k+1个字符开始,不必从第i+1个开始。

刚开始使用map做hash的实现,发现超时(map维护一个有序序列,每次插入需logN的时间,这是第二次在这里超时了,看到别人的解法后,发现可以使用unsorted_map),后改用int[256]的数组实现hash,但没做第二次优化(每次都需memset(array,-1,256*sizeof(int)) )用了42ms,后来实现做了第二次优化时间为21ms。

下面给出代码:

使用map超时代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
      map<char,int> mp;
		typedef pair<char,int> mypair;
		pair< map<char,int>::iterator,bool > pr;
		int len = s.length(),count = 0,max = 0;
		if( len <= 1 )
			return len;
		for( int i = 0; i < len ;)
		{
			pr = mp.insert( mypair(s[i],i) );
			if( pr.second )
			{
				count++;
				i++;
			}
			else
			{
				max = max > count ? max : count;
				i = pr.first->second + 1;
				count = 0;
				mp.clear();
			}
		}
		max = max > count ? max : count;
		return max;
    }
};

未做第二次优化45ms代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
     int arr[256];
		memset(arr,-1,sizeof(int)*256);
		int len = s.length(),count = 0,max = 0;
		int temp,index;
		if( len <= 1 )
			return len;
		for( int i = 0; i < len ;)
		{
			index = (int)s[i];
			temp = arr[index];
			//cout<<temp<<" "<<endl;
			if( temp == -1 )
			{
				arr[index] = i;
				count++;
				i++;
			}
			else
			{
				max = max > count ? max : count;
				i = temp + 1;
				count = 0;
				memset(arr,-1,sizeof(int)*256);
			}
		}
		max = max > count ? max : count;
		return max;
    }
};


第二次优化后21ms代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
       int arr[256];
		memset(arr,-1,sizeof(int)*256);
		int len = s.length(),count = 0,max = 0;
		int temp,index,start = 0;
		if( len <= 1 )
			return len;
		for( int i = 0; i < len ;)
		{
			index = (int)s[i];
			temp = arr[index];
			//cout<<temp<<" "<<endl;
//注意判断条件
			if( temp == -1 || temp < start)
			{
				arr[index] = i;
				count++;
				i++;
			}
			else
			{
				//在这里做出了优化,注意如何设置count值来避免每次从重复字符处开始探测
				max = max > count ? max : count;
				//i = temp + 1;
				count -= temp-start+1;
				start = temp+1;
				//memset(arr,-1,sizeof(int)*256);
			}
		}
		max = max > count ? max : count;
		return max;
    }
};



下面别人的不使用256数组的21ms的代码,不知道其优化原理:

class Solution {
public:
    int lengthOfLongestSubstring(string s)
    {
        if (s.length()==0)
        {
            return 0;
        }
        int t_nMaxLength=1,t_nLength=1;
        int t_nRepeatFlag=0;
        int t_nNoReaptLength=1;
        for (int i=0;i<s.length();i++)
        {
            int j;
            for (j=i+1+t_nNoReaptLength-1;j<s.length();++j)
            {
                t_nNoReaptLength=0;
                for (int k=i;k<j;++k)
                {
                    if (s[k]==s[j])
                    {
                        i=k;
                        t_nRepeatFlag=1;
                        t_nNoReaptLength=j-k;
                        break;
                    }
                }
                if (t_nRepeatFlag)
                {
                    t_nLength=t_nNoReaptLength;
                    t_nRepeatFlag=0;
                    break;
                }
                else
                {
                    t_nLength++;
                    if (t_nLength>t_nMaxLength)
                    {
                        t_nMaxLength=t_nLength;
                    }
                }
            }
            if (j==s.length())
            {
                break;
            }
        }
        return t_nMaxLength;
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值