题目:无重复字符的最长子串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb" 输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入:s = "pwwkew" 输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
分析
大致思路
对于该题目,我们的思路是滑块移动,给滑块设置一个起始值start和一个终值end,对字符串进行滑动,如果当前字符在我们的查找表中没有出现,表示可以继续滑动,如果当前字符在表中已经出现过了,就已经不符合题目的要求,返回此时滑块的长度即可。
具体过程
有了大致思路过后,我们再对细节进行完善,我们知道需要一个start,end来标记滑块的位置,还需要设置一个查找表,用于进行当前字符是否出现过的判断,由于共有128个字符,所以定义一个128长的空数组,并赋初值0,表示目前所有数字都没有出现过,除此之外,我们还需要定义一个maxSize来记录我们的最大长度,接着我们试着大致写一下代码。
int lengthOfLongestSubstring(char* s){
int maxSize = 0, start = 0, end = 0;
int charMap[128] = {0};
return maxSize;
}
接下来我们需要对滑块进行移动,我们首先要明确,滑块是从哪里开始移动,到什么时候结束,第一个问题很简单,从s[0]开始移动,第二个问题,当我们的end已经移动到了给定字符串的最后一位时,就不会再有下一次循环,所以结束循环条件是 end < strlen(s),对代码继续完善。
int lengthOfLongestSubstring(char* s){
int maxSize = 0, start = 0, end = 0;
int charMap[128] = {0};
while(end < strlen(s)){
}
return maxSize;
}
然后对循环体的部分进行完善,我们需要做的是将滑块进行不停的移动,如果表中有当前字符,应该将整个滑块向后移动一位,也就是start加一,如果不存在,则将end加一。现在的关键是,if语句的判断条件,我们可以通过s[i]获取到当前字符,例如s = "abcabcbb",s[1]='b',在c语言中,如果将字符串作为数组的下标,那么会自动帮我们转换成ASCII码,对于charMap[s[0]]来说,就等同于charMap[97],所以我们只需要通过charMap[s[i]],就可以判断当前字符是否在表中出现,如果出现了,charMap中对应ASCII的位置的值为TRUE;如果charMap中对应ASCII的位置的值为false,表示是第一次出现,我们不需要正在将字符存进表中,只需要将对应数组中ASCII所值的位置值再赋为true,然后对end加一即可。
int lengthOfLongestSubstring(char* s){
int maxSize = 0, start = 0, end = 0;
int charMap[128] = {0};
while(end < strlen(s)){
if(charMap[s[i]]){
charMap[s[i]] = false;
start++;
}else{
charMap[s[i]] = true;
end++;
maxSize = (end - start) > maxSize ? (end - start) : maxSize;
}
}
return maxSize;
}