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

目录

题目

[解题思路:滑动窗口 + 哈希表](#解题思路:滑动窗口 + 哈希表)

核心思想

详细实现步骤

图解示例

时间和空间复杂度

正确的写法


题目

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

解题思路:滑动窗口 + 哈希表

滑动窗口是处理子串/子数组问题的常用技巧,结合哈希表可以高效解决此问题。

核心思想

维护一个"窗口",这个窗口内的所有字符都是不重复的。当遇到重复字符时,调整窗口左边界,确保窗口内无重复字符。

详细实现步骤

  1. 初始化:
  • 创建哈希表记录字符出现次数
  • 左指针left和右指针right初始化为0
  • 最大长度ret初始化为0
  1. 扩展窗口:
  • 右指针right向右移动,将当前字符加入窗口
  • 更新哈希表中该字符的计数
  1. 处理重复:
  • 如果当前字符在窗口中已存在(计数>1)
  • 不断移动左指针left,同时减少对应字符的计数
  • 直到窗口中不再有重复字符
  1. 更新结果:
  • 每次调整窗口后,计算当前无重复子串的长度
  • 更新最大长度ret
  1. 继续扩展:
  • 右指针继续向右移动,重复步骤2-4

图解示例

以字符串 "abcabcbb" 为例:

初始状态:

XML 复制代码
字符串: a b c a b c b b
        ↑
       l,r
哈希表: {}
最大长度: 0

步骤1:右指针移动到'a'

XML 复制代码
字符串: a b c a b c b b
        ↑
       l r
哈希表: {a:1}
最大长度: 1

步骤2:右指针移动到'b'

XML 复制代码
字符串: a b c a b c b b
        ↑ ↑
        l r
哈希表: {a:1, b:1}
最大长度: 2

步骤3:右指针移动到'c'

XML 复制代码
字符串: a b c a b c b b
        ↑   ↑
        l   r
哈希表: {a:1, b:1, c:1}
最大长度: 3

步骤4:右指针移动到第二个'a'

XML 复制代码
字符串: a b c a b c b b
        ↑     ↑
        l     r
哈希表: {a:2, b:1, c:1}

发现'a'重复,移动左指针直到窗口中'a'不重复:

XML 复制代码
字符串: a b c a b c b b
          ↑   ↑
          l   r
哈希表: {a:1, b:0, c:0}
最大长度: 3

步骤5:右指针移动到第二个'b'

XML 复制代码
字符串: a b c a b c b b
          ↑     ↑
          l     r
哈希表: {a:1, b:1, c:0}
最大长度: 3

步骤6:右指针移动到第二个'c'

XML 复制代码
字符串: a b c a b c b b
          ↑       ↑
          l       r
哈希表: {a:1, b:1, c:1}
最大长度: 3

步骤7:右指针移动到第三个'b'

XML 复制代码
字符串: a b c a b c b b
          ↑         ↑
          l         r
哈希表: {a:1, b:2, c:1}

'b'重复,移动左指针:

XML 复制代码
字符串: a b c a b c b b
                ↑   ↑
                l   r
哈希表: {a:0, b:1, c:0}
最大长度: 3

步骤8:右指针移动到第四个'b'

XML 复制代码
字符串: a b c a b c b b
                ↑     ↑
                l     r
哈希表: {a:0, b:2, c:0}

'b'重复,移动左指针:

XML 复制代码
字符串: a b c a b c b b
                    ↑ ↑
                    l r
哈希表: {a:0, b:1, c:0}
最大长度: 3

最终结果:最大无重复子串长度为3

时间和空间复杂度

  • 时间复杂度:O(n),其中n是字符串长度。每个字符最多被访问两次(右指针遍历和左指针调整)。
  • 空间复杂度:O(min(m,n)),其中m是字符集大小,n是字符串长度。哈希表最多存储min(m,n)个字符。

正确的写法

cpp 复制代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int> hash;  //这里可以使用数组代替哈希表可以提高效率
        int left=0;
        int right=0;
        int ret=0;

        while(right < s.size())
        {
            hash[s[right]]++;
            while(hash[s[right]]>1)
            {
                hash[s[left++]]--;
            }

            right++;
            ret = max(ret,right-left);

            
        }
        return ret;
        
    }
};
相关推荐
Morwit5 分钟前
【力扣hot100】 1. 两数之和
数据结构·c++·算法·leetcode·职场和发展
无小道35 分钟前
算法——暴力+优化
算法·优化·暴力
Free Tester39 分钟前
如何判断 LeakCanary 报告的严重程度
java·jvm·算法
zyq99101_11 小时前
DFS算法实战:经典例题代码解析
python·算法·蓝桥杯·深度优先
智者知已应修善业1 小时前
【51单片机单按键切换广告屏】2023-5-17
c++·经验分享·笔记·算法·51单片机
广州灵眸科技有限公司1 小时前
为RK3588注入澎湃算力:RK1820 AI加速卡完整适配与评测指南
linux·网络·人工智能·物联网·算法
qinian_ztc1 小时前
frida 14.2.18 安装报错解决
算法·leetcode·职场和发展
AI应用实战 | RE2 小时前
012、检索器(Retrievers)核心:从向量库中智能查找信息
人工智能·算法·机器学习·langchain
凤年徐2 小时前
C++手撕红黑树:从0到200行,拿下STL map底层核心
c++·后端·算法
Thomas.Sir2 小时前
AI 医疗之罕见病/疑难病辅助诊断系统从算法到实现【表型驱动与知识图谱推理】
人工智能·算法·ai·知识图谱