3.无重复字符的最长子串(力扣hot100)

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

示例 1:

输入:s="abcabcbb"

输出:3

解释:因为无重复字符的最长子串是"abc",所以其长度为 3.

示例 2:

输入:s ="bbbbb"

输出:1

解释:因为无重复字符的最长子串是"b"所以其长度为 1。

示例 3:

输入:s ="pwwkew'

输出:3

解释:因为无重复字符的最长子串是"wke",所以其长度为 3.

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

提示:

0<= s.length <= 5*104

s由英文字母、数字、符号和空格组成

2024年9月5日,第二道hot100中难度题。

解题思路:临时空间用于存储子串,临时空间不停地更新最新的最长子串,直到s全部遍历。将最终子串拷贝到最后的结果中。

需要考虑的点:1)s遍历结束都没有重复,需要在for结束后拷贝整个临时数组;2)有重复,则需要处理临时数组,找到临时数组中哪个字符开始重复,然后将后面的所有字符都前移,然后与ret中的子串判断,看是否需要更新ret。(最开始直接将字符前移到s出现重复的字符处,会导致子串漏掉)

我的代码中存在的问题:1)不需要使用calloc,只需要使用临时数组即可;2)所有的ASCII字符只有128个,所有数组大小为128;3)时间复杂度为O(n²);4)空间复杂度也多了一倍!用到了两个临时数组;

改进法:使用窗口滑动法;时间复杂度为O(n);

用时:第一次看题+编码耗时30分钟,vs调试耗时27+60+60;大致耗时3小时。

c 复制代码
int lengthOfLongestSubstring(char* s) 
{
    char* sRet = (char*)calloc(129, sizeof(char));
    char* sTmp = (char*)calloc(129, sizeof(char));
    if (sRet == NULL || sTmp == NULL || s == NULL)
        return 0;
    int iLastLen = 0, iSlen = strlen(s);
    bool bRepeat = 0;

    for (int i = 0; i < iSlen; i++)
    {
        bRepeat = 0;
        int iCurTmpLen = strlen(sTmp);
        //判断当前s字符串的字符是否与sTmp子串有重复
        int j = 0;
        for (j = 0; j < iCurTmpLen; j++)
        {
            if (sTmp[j] == s[i])
            {
                bRepeat = 1;
                break;
            }
        }
        sTmp[iCurTmpLen++] = s[i];
        if (bRepeat)
        {
            if (iCurTmpLen > iLastLen)
            {
                memcpy(sRet, sTmp, iCurTmpLen-1);
                iLastLen = iCurTmpLen-1;
            }
            int iTmp = 0;
            for (int k = j+1; k < iCurTmpLen; k++)
            {
                sTmp[iTmp++] = sTmp[k];
            }
            //清空sTmp后面的垃圾数据
            memset(sTmp+ iTmp, 0, 129-iTmp);
        }
    }
    memcpy(sRet, sTmp, strlen(sTmp));
    iLastLen = strlen(sRet);
    free(sTmp);
    free(sRet);

    return iLastLen;
}

chatgpt代码(滑动窗口法):

c 复制代码
int lengthOfLongestSubstring(char* s) {
    int n = strlen(s);
    if (n == 0) return 0;

    int maxLength = 0;
    int start = 0;  // 滑动窗口的起点
    int lastIndex[128];  // 存储字符上次出现的位置,假设字符集为ASCII(共128个字符)

    // 初始化 lastIndex 数组为 -1,表示字符还没有出现过
    for (int i = 0; i < 128; i++) {
        lastIndex[i] = -1;
    }

    // 遍历字符串
    for (int i = 0; i < n; i++) {
        char currentChar = s[i];

        // 如果当前字符在滑动窗口内已经出现过,移动窗口的起点
        if (lastIndex[currentChar] >= start) {
            start = lastIndex[currentChar] + 1;
        }

        // 更新字符的最新出现位置
        lastIndex[currentChar] = i;

        // 更新最大长度
        int currentLength = i - start + 1;
        if (currentLength > maxLength) {
            maxLength = currentLength;
        }
    }

    return maxLength;
}
相关推荐
Bucai_不才15 分钟前
【C++】初识C++之C语言加入光荣的进化(下)
c语言·c++·面向对象编程
浊酒南街22 分钟前
决策树(理论知识3)
算法·决策树·机器学习
A懿轩A30 分钟前
C/C++ 数据结构与算法【哈夫曼树】 哈夫曼树详细解析【日常学习,考研必备】带图+详细代码
c语言·c++·学习·算法·哈夫曼树·王卓
思码逸研发效能40 分钟前
在 DevOps 中,如何应对技术债务和系统复杂性,以确保可持续的研发效能和创新?
运维·算法·研发效能·devops·研发效能度量·效能度量
LuckyRich11 小时前
【贪心算法】贪心算法七
算法·贪心算法·哈希算法
HEU_firejef1 小时前
面试经典 150 题——数组/字符串(一)
数据结构·算法·面试
chenziang12 小时前
leetcode hot 全部子集
算法·leetcode·职场和发展
EdwardYange2 小时前
LeetCode 83 :删除排链表中的重复元素
数据结构·算法·leetcode·链表
nuyoah♂2 小时前
DAY37|动态规划Part05|完全背包理论基础、LeetCode:518. 零钱兑换 II、377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)
算法·leetcode·动态规划
编程探索者小陈2 小时前
【优先算法】专题——二分查找算法
算法