给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 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;
}