LeetCode 第3题:无重复字符的最长子串
LeetCode 第3题:无重复字符的最长子串
题目描述
给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。
难度
中等
题目链接
https://leetcode.cn/problems/longest-substring-without-repeating-characters/
示例
示例 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 由英文字母、数字、符号和空格组成
解题思路
方法一:滑动窗口
这道题可以使用滑动窗口的方法解决。滑动窗口是一种在数组或字符串上使用双指针的技巧,通过移动左右指针形成一个窗口,在窗口内进行操作。
关键点:
- 使用两个指针(left和right)维护一个滑动窗口
- 使用HashSet记录窗口内的字符,保证无重复
- 当遇到重复字符时,移动左指针直到删除重复字符
- 在移动过程中更新最大长度
具体步骤:
- 初始化左指针left = 0,右指针right = 0
- 创建HashSet存储窗口内的字符
- 移动右指针,将字符加入Set:
- 如果字符不在Set中,加入Set并更新最大长度
- 如果字符在Set中,移动左指针并删除字符,直到没有重复
 
- 重复步骤3直到右指针到达字符串末尾
时间复杂度:O(n),其中n是字符串长度
空间复杂度:O(min(m,n)),其中m是字符集大小
方法二:优化的滑动窗口
使用Dictionary/HashMap代替HashSet,存储字符最后出现的位置,可以直接跳转左指针位置,避免一个个删除字符。
代码实现
C# 实现(基本滑动窗口)
public class Solution {
    public int LengthOfLongestSubstring(string s) {
        // 特殊情况处理
        if (string.IsNullOrEmpty(s)) return 0;
        // 创建HashSet存储当前窗口中的字符
        HashSet<char> window = new HashSet<char>();
        int maxLength = 0;
        int left = 0;
        // 右指针遍历字符串
        for (int right = 0; right < s.Length; right++) {
            // 如果发现重复字符,移动左指针直到删除重复字符
            while (window.Contains(s[right])) {
                window.Remove(s[left]);
                left++;
            }
            // 将当前字符加入窗口
            window.Add(s[right]);
            // 更新最大长度
            maxLength = Math.Max(maxLength, right - left + 1);
        }
        return maxLength;
    }
}
C# 实现(优化的滑动窗口)
public class Solution {
    public int LengthOfLongestSubstring(string s) {
        // 特殊情况处理
        if (string.IsNullOrEmpty(s)) return 0;
        // 创建Dictionary存储字符最后出现的位置
        Dictionary<char, int> lastPos = new Dictionary<char, int>();
        int maxLength = 0;
        int left = 0;
        // 右指针遍历字符串
        for (int right = 0; right < s.Length; right++) {
            char currentChar = s[right];
            // 如果字符已存在,直接将左指针移动到重复字符的下一位
            if (lastPos.ContainsKey(currentChar)) {
                left = Math.Max(left, lastPos[currentChar] + 1);
            }
            // 更新字符最后出现的位置
            lastPos[currentChar] = right;
            // 更新最大长度
            maxLength = Math.Max(maxLength, right - left + 1);
        }
        return maxLength;
    }
}
代码详解
基本滑动窗口版本:
- HashSet<char> window:用于存储当前窗口中的字符,保证无重复
- while (window.Contains(s[right])):当发现重复字符时,不断移动左指针并删除字符
- maxLength = Math.Max(maxLength, right - left + 1):更新最大长度
优化版本:
- Dictionary<char, int> lastPos:存储每个字符最后出现的位置
- left = Math.Max(left, lastPos[currentChar] + 1):- 当发现重复字符时,直接将左指针移动到重复字符上次出现位置的下一位
- 使用Math.Max是为了防止左指针回退
 
执行结果
基本滑动窗口版本:
- 执行用时:84 ms
- 内存消耗:39.5 MB
优化版本:
- 执行用时:72 ms
- 内存消耗:39.8 MB
总结与反思
- 这是一道经典的滑动窗口题目,考察了:
- 滑动窗口的基本应用
- 字符串的处理
- 哈希表的使用
 
- 两种实现方式各有优势:
- 基本版本思路更直观,易于理解
- 优化版本性能更好,避免了多次移动左指针
 
- 关键点:
- 理解子串和子序列的区别
- 正确维护滑动窗口
- 高效处理重复字符
 
相关题目
- LeetCode 第159题:至多包含两个不同字符的最长子串
- LeetCode 第340题:至多包含 K 个不同字符的最长子串
- LeetCode 第395题:至少有 K 个重复字符的最长子串
- LeetCode 第424题:替换后的最长重复字符
LeetCode 第3题:无重复字符的最长子串的更多相关文章
- LeetCode 第三题--无重复字符的最长子串
		1. 题目 2.题目分析与思路 3.思路 1. 题目 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3 ... 
- Leetcode(3)无重复字符的最长子串
		Leetcode(3)无重复字符的最长子串 [题目表述]: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 第一种方法:暴力 执行用时:996 ms: 内存消耗:12.9MB 效果: ... 
- LeetCode刷题--无重复字符的最长子串(中等)
		题目描述: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 " ... 
- 【LeetCode题解】3_无重复字符的最长子串(Longest-Substring-Without-Repeating-Characters)
		目录 描述 解法一:暴力枚举法(Time Limit Exceeded) 思路 Java 实现 Python 实现 复杂度分析 解法二:滑动窗口(双指针) 思路 Java 实现 Python 实现 复 ... 
- leetcode题解#3:无重复字符的最长子串
		leetcode题解:无重复字符的最长子串 题目 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: s = "abcabcbb"输出: 3 解释 ... 
- Leetcode(3)-无重复字符的最长子串
		给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 &q ... 
- LeetCode 第 3 题:无重复字符的最长子串(滑动窗口)
		LeetCode 第 3 题:无重复字符的最长子串 (滑动窗口) 方法:滑动窗口 滑动窗口模板问题:右指针先走,满足了一定条件以后,左指针向前走,直到不满足条件. 特点:左右指针的方向是一致的,并且是 ... 
- leetcode刷题第三天<无重复字符的最长子串>
		给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 : 输入: "abcabcbb" 输出: 解释: 因为无重复字符的最长子串是 . 示例 : 输入: &quo ... 
- leetcode刷题笔记-3. 无重复字符的最长子串(java实现)
		题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "ab ... 
- LeetCode随缘刷题之无重复字符的最长子串
		欢迎评论区交流. package leetcode.day_12_04; /** * 给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度. * <p> * 示例1: * &l ... 
随机推荐
- Linux管道命令
			Linux中常用文件字符串分析的命令 在linux中文件管理与系统管理的方面,经常会用到要从一个文件中或者一长串字符串中提取你所需要的数据,或者某些字段来进行查看或者分析,作为一个初级linux小菜鸟 ... 
- 多线程实现的Java爬虫程序
			以下是一个Java爬虫程序,它能从指定主页开始,按照指定的深度抓取该站点域名下的网页并维护简单索引. 参数:private static int webDepth = 2;//爬虫深度. 主页的深度为 ... 
- Graylog之告警
			官方文档:https://docs.graylog.org/en/3.0/index.html 前面我们已经了解了Graylog的搭建,以及日志的接入方法.我们知道graylog可以将收集的的日志通过 ... 
- 2023 CCPC 深圳
			2023 CCPC 深圳 D. Bot Brothers 有一棵 \(n\) 个点的树,\(m\) 个叶子,编号为 \(1∼m\).两人在树上博弈,均从根出发,轮流行动,每次走向一个当前所在节点的子节 ... 
- Filter内存马
			概述 最近感冒了,不想BB太多,直接开始调试吧,先写个Filter来调试 Filter代码 新建一个FilterShell类,代码如下: 一个类如果想要成为Filter则需要继承Filter,然后重写 ... 
- Natasha v9.0 为 .NET 开发者提供 [热执行] 方案.
			项目简介 自 Natasha v9.0 发布起,我将基于 Natasha 的推出热执行方案,这项技术允许基于 控制台(Console) 和新版 Asp.net Core 架构的项目在运行中动态重编译, ... 
- fastadmin表格 - 自定义接口
			1.文本过长溢出 文本超过250px则隐藏,如果需要修改此宽度,请在具体页面中重新定义formatter方法 点击通过弹窗展示完整的内容 弹窗插件使用Layer.js 调用方法 {field: 'co ... 
- Javascript Dom元素信息
			1.Dom元素的大小 属性 说明 调用者 offsetWidth,offsetHeight 返回元素的宽高(border+padding) ,整数 当前Dom元素 clientWidth,client ... 
- 构建交互式聊天界面:react-chat-element 实战小计
			react聊天组件库:react-chat-elements 需求场景:用户可以通过多元的用户交互方式,如文件.图片.声音以及文字等输入相关信息,AI给出对应的回答 react-chat-elemen ... 
- 前端每日一知之让Chrome支持小于12px的文字
			脑图在线链接 本文内容依据[js每日一题]公众号精彩文章总结而来 
