【中等】力扣算法题解析LeetCode3:无重复字符的最长子串

关注文末推广名片,即可免费获得本题测试源码

题目来源:LeetCode 3:无重复字符的最长子串

问题抽象: 给定一个字符串 s(长度 ≥ 0),要求找到其所有子串中 不包含重复字符 的最长子串的长度,满足以下核心需求:

  1. 子串定义

    • 子串必须是字符串中 连续的字符序列
    • 子串中所有字符必须 唯一(无重复字符)。
  2. 计算约束

    • 时间复杂度 O(n)(n 为字符串长度),空间复杂度 O(min(m, n))(m 为字符集大小);
    • 需通过 滑动窗口哈希映射 实现:
      • 维护窗口 [start, end],记录字符最后出现位置;
      • 遇到重复字符时,移动 start 到重复字符的下一个位置。
  3. 边界处理

    • 空字符串 → 返回 0;
    • 全唯一字符 → 返回字符串长度;
    • 特殊用例:
      • s="abcabcbb" → 输出 3(“abc”);
      • s="bbbbb" → 输出 1(“b”);
      • s="pwwkew" → 输出 3(“wke” 或 “kew”)。

输入:字符串 s
输出:整数值(最长无重复字符子串的长度)。


解题思路

要找到字符串中不含有重复字符的最长子串,可以使用滑动窗口(双指针) 的方法。具体思路如下:

  1. 初始化:使用两个指针 startend 表示当前窗口的起始和结束位置,初始时两者都为0。同时,使用一个数组 lastOccurrence 记录每个字符最后一次出现的位置(初始值为-1)。

  2. 遍历字符串:移动 end 指针遍历每个字符:

    • 如果当前字符在 lastOccurrence 中记录的位置大于等于 start,说明该字符在当前窗口内重复出现,需要移动 start 指针到该字符上次出现位置的下一位。
    • 更新当前字符的最后出现位置为当前 end 指针的位置。
    • 计算当前窗口的长度(end - start + 1),并更新最大长度。
  3. 返回结果:遍历结束后,返回记录的最大长度。

本方法通过一次遍历即可完成,时间复杂度为 O(n),空间复杂度为 O(1)(因为字符集大小固定)。


代码实现(Java版)🔥点击下载源码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 记录每个字符最后一次出现的位置
        int[] lastOccurrence = new int[128];
        // 初始化数组,-1表示未出现过
        for (int i = 0; i < 128; i++) {
            lastOccurrence[i] = -1;
        }
        int start = 0; // 窗口起始位置
        int maxLength = 0; // 最大长度
        
        for (int end = 0; end < s.length(); end++) {
            char c = s.charAt(end);
            // 如果当前字符在窗口内重复出现,移动start指针
            if (lastOccurrence[c] >= start) {
                start = lastOccurrence[c] + 1;
            }
            // 更新当前字符的最后出现位置
            lastOccurrence[c] = end;
            // 计算当前窗口长度并更新最大值
            maxLength = Math.max(maxLength, end - start + 1);
        }
        
        return maxLength;
    }
}

代码说明

  • 初始化数组lastOccurrence 数组用于记录每个字符的最后出现位置,初始化为-1。
  • 滑动窗口:通过 startend 指针维护当前无重复字符的子串窗口。
  • 更新策略:当遇到重复字符时,将 start 指针移动到重复字符上次出现位置的下一位,确保窗口内无重复字符。
  • 效率:该算法只需遍历字符串一次,时间复杂度为 O(n),空间复杂度为 O(1)(固定大小的数组)。

提交详情(执行用时、内存消耗)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值