leetcode 3 无重复最长子串(c语言)【使用滑动窗口】

 

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

示例 1:

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

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

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
思路:首先要考虑字符集是只有字母还是数字+字母 还是所有的ascll码 ,重复字母对大小写是否敏感。

假设现在考察的s[i...j]这个子串,如果现在子串中还没有重复字母的话,我们为了要找到最长的子串,就应该试着向后扩展一位,看一下一个字符是否和当前的字符串产生了重复的字母,如果没有产生的话,我们的J就可以放心的向后++。此时,我们就找到了一个更长的没有重复字母的子串s[i...j+1]。这个过程依次类推,我们一直尝试增加j来找到一个更长的子串来。让这个子串没有重复的字母。直到某一刻,我们要考察的下一个字符和子串中的某一个字符产生了重复的字符。如下图 j+1 位置上的字符和子串中的某一个字符重复,当前这个子串就无法继续向前扩展了。此时,我们找到的一个暂子串时从i到j就是一个没有重复的字母的子串,记录长度看是否比当前更长的一个长度。之后i++把重复的字符丢弃,此时j包含刚才那个重复的字符,重复的字符已经从i哪里被丢弃了,形成了一个新的没有重复字符的子串 j 继续向前扩展 重复以上步骤 试图找到一个最长的子串没有重复的字母,整个过程i和j形成了一个滑动窗口不断向前滑动,找到满足题意的解,来记录子串的长度是否是一个更长的子串。还有一个问题,还有一个问题,我们如何确定下一个字符和子串中没有重复的字符?设置一个数组freq[256],freq[k]存的就是ascll码为k的字符在子串中出现的频率,使用这种方法就可以面对下一个字符查找在,freq中的频率值是多少0没有重复1产生了一个重复的字符。

 

#define max(a,b) a>b?a:b
int lengthOfSubstring(char *s)
{
	int freq[256]={0};//初始化所有元素频率为0
	int l =0,r=-1;// 滑动窗口为[l...r]l=0 r=-1 初始为空 
	int res = 0;//满足条件的最长子串的长度 
	int len = strlen(s);
	while(l<len)
	{//如果没有越界 且 满足没有重复的字符 
		if(r+1<len&&freq[s[r+1]]==0)
		{
			r++;
			freq[s[r]]++;
		}
		else
		{
			freq[s[l]]--;
			l++;
		}
		//到这 已经形成了一个新的子串
		res = max(res,r-l+1); //对当前子串的长度和已经找到的子串长度对比找到最大的 
	} 
	return res; 
	 
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值