LeetCode 3 无重复字符的最长子串 C语言

题目

3. 无重复字符的最长子串

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

示例 :

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

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

示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。

请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

思路一(双层循环)

首先两个指针,尾指针停留在第一个开始遍历的字符,头指针往后走进行遍历,再使用一个数组将正在遍历的字符对应的ASCII码作为下标改变数组中的值,即num[s[rear]] = rear + 1; 这里我第一次写的时候本想用0和1作为标记,但这样存在尾指针每移动一次整个数组需要重新置为0的问题,后来就优化为rear + 1,头指针遍历到对应数组中的值为rear + 1时即表示字符重复,尾指针后移

代码实现

int head, rear = 0, len = 0;
    int num[127] = {0};
    int n = strlen(s);
    while(rear < n) {
        if(n - rear < len) { //剩下字符长度小于已有最长字符串长度则不用进行计算
            break;
        }
        num[s[rear]] = rear + 1;
        head = rear + 1;
        while(num[s[head]] != rear + 1 && head < n) {
            num[s[head]] = rear + 1;
            head++;
        }
        if(head - rear > len) {
            len = head - rear;
        }
        rear++;
    }
    return len;

思路二(单层循环)

这个方法是我在题解中看到的,觉得我想不到,就记下来

首先和思路一一样,两个指针,尾指针初始化在第一个开始遍历的字符,头指针往后走进行遍历,再使用一个数组将正在遍历的字符对应的ASCII码作为下标改变数组中的值,赋值为头指针的下一个。当数组中值不为0时,尾指针赋值为数组中值,即在上次相同值之后。这里尾指针仅用于计算长度,头指针在遍历
借用题解中图,图中i为尾指针,flag为头指针:
在这里插入图片描述

扫描二维码关注公众号,回复: 11490336 查看本文章

代码实现

int head, rear = 0, len = 0;
    int table[127] = {0};
    int strSize = strlen(s);
    for(head = 0; head < strSize; head++){
        int index = (int)s[head];
        if(table[index] != 0){
            rear = (table[index] >= rear) ? table[index] : rear;
        }
        len = (len >= head - rear + 1) ? len : head - rear + 1;
        table[index] = head + 1;
    }
    return len;

猜你喜欢

转载自blog.csdn.net/streamery/article/details/104742154