【LeetCode刷题练习】(3)无重复字符的最长子串 Longest Substring Without Repeating Characters

无重复字符的最长子串 Longest Substring Without Repeating Characters

题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例

输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。

请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

思路
1.暴力解法:遍历所给字符串,逐个求出所有小于等于总字符串长度的子字符串,并计算每一个子字符串长度,再比较其内部是否有重复字符,求出无重复字符的最长子字符串。但该解法时间复杂度较高。参阅题解采用方法二。

2.滑动窗口法:在字符串中设置一个初始长度为0的滑动窗口 [ head , rear ),此时 head = rear ,将滑动窗口内部看作一个队列,将字符逐个存储到滑动窗口中,若窗口外下一个字符与窗口内字符不重复,则将窗口长度+1,并向右滑动 rear ,直至下一个字符与窗口内字符重复,则此时,我们找到的没有重复字符的最长子字符串是以 head 开头的不重复最长子串。对字符串中所有的head做此操作,即对字符串中每一个字符都采取rear右滑,记录以其开头的不重复最长子串,最后比较得到最长子串。

代码

int lengthOfLongestSubstring(char * s){    
	int maxStrLen = 0;          //不重复字符的最长子串长度,即题目所求    
	int winLen = 0;             //滑动窗口长度、队列头尾    
	int winHead = 0;    
	int winRear = 0;    
	int winQueue[128] = {0};    //ASCII码有128个字符,滑动窗口内最多有128个不重复字符    
	int strLength = strlen(s);  //字符串长度    

	if(strLength == 0){        
		return 0;               //字符串为空返回0    
	}    
	while(winHead <= (strLength-1)){   //对每一个字符用滑动窗口遍历字符串        
		if(winQueue[s[winHead]]!=0){    //当滑动窗口不为空时开始查找窗口内重复字符            
			if(winQueue[s[winHead] ] > winRear){    //滑动窗口下一个字符蝠时,忽视外部子字符串                
				winRear = winQueue[s[winHead]];     //更新滑动窗口队尾,即rear右滑一个单位            
			}        
		}        
		winLen = winHead - winRear + 1;    //更新计算滑动窗口长度        
		if(winLen > maxStrLen){             //若滑动窗口长度大于目前不重复子串长度            
			maxStrLen = winLen ;            //则更新最大不重复子串长度为窗口长度        
		}         
		winQueue[s[winHead]] = winHead + 1;//存储字符串head字符的位置到队列中
		winHead++;			//,以head++字符开始滑动窗口遍历                             
	}    
	return maxStrLen;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值