每天一道LeetCode-03(无重复字符的最长子串)

64 阅读2分钟

题目:无重复字符的最长子串

给定一个字符串 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;
}