Longest Substring Without Repeating Characters

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.

第一次用简单的方法,即 f(i,j)寻找,统计最大的值。刚开始报超时,以为是代码时间复杂度较高,改成后面优化的代码仍然如此,参考他人发现不会。继续寻找代码问题。改了一上午,都快无语了。最终发现原来是溢出问题char str_num[256] ; 改为int str_num[256] ;好了。前面char型应付小的字符串,即长度低于256的可以,超过则出错!总结一句话,小心。多检查代码,多做防错处理!

int lengthOfLongestSubstring(string s)
{

	int str_num[256] ;//字符不止26个
	int max_len = 0;

	fill(str_num,str_num+256,-1);
	int  sub_max_len = 0;
	int start = 0;
	for(int i = 0;i < s.size();i++)
	{

		if(str_num[s[i]] >=  0 )
		{
			if(sub_max_len > max_len)
			{
				max_len = sub_max_len;
			}
			int temp = i;
			i = str_num[s[i]] ;//之后i 自己会自增
			start = i+1;
			 
			sub_max_len = 0;//重新初始化
			
			for (int k= start; k <= temp;k++)
			{
				str_num[s[k]] = -1;
			}
			
		}
		else
		{
			str_num[s[i]] = i;
			sub_max_len ++;
		}

	}
	return max(max_len,sub_max_len);
}

思路二:由于上面的字符串重复检查复杂度高。当发生重复时,没必要从开始的下一个,可以重复的下一个开始,从而避免大量的重复工作复杂度降为O(n)


如上图:x重复,从x的下一个r开始统计!

 int lengthOfLongestSubstring(string s) {
       
       int str_num[256] ;//字符不止26个
       int max_len = 0;
       
        fill(str_num,str_num+256,-1);
        int  sub_max_len = 0;
        
       for(int i = 0;i < s.size();i++)
       {
          
            if(str_num[s[i]] >= 0)//大于0表示存在
            {
                
                if(sub_max_len > max_len)
                {
                    max_len = sub_max_len;
                }
                i = str_num[s[i]] ;//之后i 自己会自增 (回溯)
                
                sub_max_len = 0;//重新初始化
                fill(str_num,str_num+256,-1);//将中间的字符标志设为-1,重新开始检查
            }
           else
           {
                str_num[s[i]] = i;//更新位置信息
                sub_max_len ++;
           }
            
       }
        return max(max_len,sub_max_len);
    }

第三次:避免了每次清除中间位置信息的工作。通过start位置 与当前i位置确定中间信息,并且实时更新str_num[s[i]]。str_num[s[i]] >=  start来定位是否现在的字段有重复

int lengthOfLongestSubstring(string s)
{

	int str_num[256] ;//字符不止26个
	int max_len = 0;

	fill(str_num,str_num+256,-1);
	int  sub_max_len = 0;
	int start = 0;
	for(int i = 0;i < s.size();i++)
	{

		if(str_num[s[i]] >=  start )//大于起始位置,表明中间有重复!!
		{
		
	                sub_max_len = i - start ;
			if(sub_max_len > max_len)
			{
				max_len = sub_max_len;
			}
			start = str_num[s[i]]+1;
		}			
		str_num[s[i]] = i;
		
	}
	int len = s.size()-start;
	return max(max_len,len);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值