LeetCode--3. 无重复字符的最长子串(双指针)

无重复字符的最长子串(C)

1. 题目描述

难度:中等
在这里插入图片描述

2. 题目分析

这道题目是一道中等难度的题目,我们需要知道的有一点:

  • 字符串中有包括空字符的所有字符,不止英文字母
    这一点很重要,因为在刚接触这道题的时候,很容易当成字符串中只有英文字符,这在使用ASCII码的时候会有麻烦。

这道题当然可以使用暴力穷举法,求出所有可能的字符串,并选出合适的字符串并输出最大长度,这么做的话时间复杂度太高了。有一种方法可以使时间复杂度为O(n),那就是双指针法。

  • 双指针法
    定义两个指针,一个头指针用来指向字符串的头,一个指针用来滑动。申请一个128个元素的数组空间,用来表示当前字符串是否有重复的元素。为什么大小为128?因为根据ASCII码表,一共有128个元素(包含空元素)。举个例子:如果滑动指针指向的是字符‘a’,该字符对应的ASCII码表为97,所以在新建的数组的下标为97的空间存储为1。滑动指针滑动的时候,一直判断指向的元素所对应的新建数组中的元素是否为1,如果是1那么表示该元素在之前已经初出现,如果是0,表示该元素在之前并没有出现。具体代码见第三节。

3. C语言实现

代码如下:

int lengthOfLongestSubstring(char * s){
	/***
	参数列表:
	i:滑动指针; index:头指针; len:字符串长度; 
	label:字符对应的下标; max: 字符串长度最大值
	count: 滑动过程中字符串的长度
    ***/
    int i, index, len, max, label, count;
    // 初始化变量以及申请数组空间
    max = 0;
    count = 0;
    index = 0;
    len = strlen(s);
    int *temp = (int *)malloc(sizeof(int)*128);
	// 开始循环
    for(i = 0; i < len; i++){
        label = (int)(s[i]);
        // 如果字符之前没有出现
        if(temp[label] != 1){
        	// 在相应的位置上置1,长度加一
            temp[label] = 1;
            count++;
        }
        // 如果字符在之前已经出现
        else{
        	// 将头指针移动得到重复字符的后一位
            while(s[index] != s[i]){
                temp[(int)(s[index])] = 0;
                index++;
            } 
            index++;
            count = i - index + 1;
        }
        // 更新最大长度值
        max = max>count?max:count;
    }
    return max;
}

运行结果为:
在这里插入图片描述

发布了163 篇原创文章 · 获赞 188 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_42580947/article/details/104758849