代码训练LeetCode(41)无重复字符的最长子串

代码训练(41)无重复字符的最长子串

Author: Once Day Date: 2025年6月28日

漫漫长路,才刚刚开始…

全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客

参考文章:

1. 原题

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

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
2. 分析

这个题目要求我们找出给定字符串中最长的不含重复字符的子串,并返回这个子串的长度。字符串可能由英文字母、数字、符号和空格组成。

为了解决这个问题,我们可以使用滑动窗口的方法。滑动窗口是一种可以将嵌套的循环问题转换为单循环问题,从而降低时间复杂度的技术。具体到这个问题,我们可以定义两个指针,一个指向子串的开始位置,另一个随着遍历逐步向后移动,从而形成一个窗口。我们还需要一个数据结构来存储窗口内的字符,以快速判断字符是否重复,通常使用哈希表实现。

分析步骤:

  1. 初始化两个指针 left 和 right,分别代表子串的起始和结束位置,初始化哈希表用于存储字符及其在字符串中的位置。
  2. 遍历字符串,对于每个字符:
    • 如果字符已经在哈希表中且其索引不小于 left,说明窗口内有重复字符,需要移动 left 指针到重复字符的下一个位置。
    • 更新哈希表中当前字符的位置。
    • 更新最大子串长度。
  3. 返回记录的最大长度。

举例分析:例如,对于字符串 “abcabcbb”:

  • 初始化 left=0, right=0, 最大长度 max_len=0。
  • right=0,字符 ‘a’,哈希表更新为 {‘a’: 0},max_len 更新为 1。
  • right=1,字符 ‘b’,哈希表更新为 {‘a’: 0, ‘b’: 1},max_len 更新为 2。
  • right=2,字符 ‘c’,哈希表更新为 {‘a’: 0, ‘b’: 1, ‘c’: 2},max_len 更新为 3。
  • right=3,字符 ‘a’ 重复,left 更新为 1,哈希表更新为 {‘a’: 3, ‘b’: 1, ‘c’: 2}。
  • 依此类推,直到遍历完整个字符串。

性能优化关键点:

  • 使用哈希表来快速查找和更新字符的位置。
  • 只需遍历一次字符串,时间复杂度为 O(n)。
  • 空间复杂度主要由哈希表引起,最坏情况下为 O(min(m, n)),其中 m 是字符集的大小。
3. 代码实现
#include <stdio.h>
#include <string.h>
#define MAX_CHARS 256

int lengthOfLongestSubstring(char * s) {
    int n = strlen(s);
    int longest = 0;
    int left = 0;
    int charIndex[MAX_CHARS]; // 存储每个字符的最新位置
    memset(charIndex, -1, sizeof(charIndex));

    for (int right = 0; right < n; right++) {
        if (charIndex[s[right]] >= left) {
            left = charIndex[s[right]] + 1;
        }
        charIndex[s[right]] = right;
        longest = longest > right - left + 1 ? longest : right - left + 1;
    }
    return longest;
}

int main() {
    char s[] = "abcabcbb";
    printf("The length of the longest substring without repeating characters is: %d\n", lengthOfLongestSubstring(s));
    return 0;
}
4. 总结

这个问题考察了对滑动窗口技术的理解和应用,以及对数据结构(如哈希表)的使用来优化查找和更新操作。通过这类问题,可以提升对字符串处理和算法优化的能力。要进一步提高,可以练习更多涉及滑动窗口和字符串处理的问题,同时也要注意边界条件和特殊输入的处理。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值