3
无重复字符的最长子串
中等频率: 1033
146
LRU缓存机制
中等频率: 818
206
反转链表
简单频率: 712
215
数组中的第K个最大元素
中等频率: 554
25
K个一组翻转链表
困难频率: 475
15
三数之和
中等频率: 439
53
最大子数组和
中等频率: 354
912
排序数组
中等频率: 327
21
合并两个有序链表
简单频率: 310
5
最长回文子串
中等频率: 308
200
岛屿数量
中等频率: 295
33
搜索旋转排序数组
中等频率: 290
46
全排列
中等频率: 282
88
合并两个有序数组
简单频率: 274
20
有效的括号
简单频率: 267
121
买卖股票的最佳时机
简单频率: 259
236
二叉树的最近公共祖先
中等频率: 254
92
反转链表 II
中等频率: 253
141
环形链表
简单频率: 246
300
最长上升子序列
中等频率: 240
54
螺旋矩阵
中等频率: 239
143
重排链表
中等频率: 230
23
合并K个排序链表
困难频率: 225
415
字符串相加
简单频率: 213
56
合并区间
中等频率: 211
160
相交链表
简单频率: 197
42
接雨水
困难频率: 186
1143
最长公共子序列
中等频率: 174
124
二叉树中的最大路径和
困难频率: 174
93
复原IP地址
中等频率: 171
82
删除排序链表中的重复元素 II
中等频率: 170
19
删除链表的倒数第N个节点
中等频率: 169
142
环形链表 II
中等频率: 165
4
寻找两个正序数组的中位数
困难频率: 158
199
二叉树的右视图
中等频率: 150
165
比较版本号
中等频率: 148
704
二分查找
简单频率: 140
22
括号生成
中等频率: 139
94
二叉树的中序遍历
简单频率: 139
239
滑动窗口最大值
困难频率: 137
69
x 的平方根
简单频率: 135
148
排序链表
中等频率: 135
32
最长有效括号
困难频率: 134
31
下一个排列
中等频率: 132
8
字符串转换整数 (atoi)
中等频率: 129
70
爬楼梯
简单频率: 124
322
零钱兑换
中等频率: 123
43
字符串相乘
中等频率: 120
76
最小覆盖子串
困难频率: 117
41
缺失的第一个正数
困难频率: 108
105
从前序与中序遍历序列构造二叉树
中等频率: 106
78
子集
中等频率: 102
151
翻转字符串里的单词
中等频率: 101
155
最小栈
简单频率: 96
34
在排序数组中查找元素的第一个和最后一个位置
中等频率: 94
394
字符串解码
中等频率: 91
101
对称二叉树
简单频率: 91
39
组合总和
中等频率: 89
470
用 Rand7() 实现 Rand10()
中等频率: 87
64
最小路径和
中等频率: 87
104
二叉树的最大深度
简单频率: 87
110
平衡二叉树
简单频率: 85
144
二叉树的前序遍历
简单频率: 84
48
旋转图像
中等频率: 82
234
回文链表
简单频率: 82
695
岛屿的最大面积
中等频率: 82
122
买卖股票的最佳时机 II
简单频率: 82
240
搜索二维矩阵 II
中等频率: 81
221
最大正方形
中等频率: 81
98
验证二叉搜索树
中等频率: 80
543
二叉树的直径
简单频率: 79
14
最长公共前缀
简单频率: 78
179
最大数
中等频率: 76
113
路径总和 II
中等频率: 76
662
二叉树最大宽度
中等频率: 76
62
不同路径
中等频率: 73
198
打家劫舍
中等频率: 71
152
乘积最大子数组
中等频率: 71
560
和为K的子数组
中等频率: 70
112
路径总和
简单频率: 68
226
翻转二叉树
简单频率: 67
209
长度最小的子数组
中等频率: 67
227
基本计算器 II
中等频率: 67
169
多数元素
简单频率: 67
24
两两交换链表中的节点
中等频率: 66
139
单词拆分
中等频率: 65
283
移动零
简单频率: 64
718
最长重复子数组
中等频率: 64
1
两数之和
简单频率: 5
2
两数相加
中等频率: 4

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

查看题目
中等
哈希表
字符串
滑动窗口
双指针
频率: 1033

解法滑动窗口

时间复杂度:O(n) | 空间复杂度:O(min(m,n)) | 推荐使用

动画演示

准备就绪 - 点击开始按钮查看动画

代码实现

class Solution {
    /**
     * 滑动窗口解法
     * 使用左右指针维护一个不包含重复字符的窗口
     */
    public int lengthOfLongestSubstring(String s) {
        // 使用HashMap记录字符最后出现的位置
        Map<Character, Integer> charMap = new HashMap<>();
        int left = 0;
        int maxLength = 0;
        
        for (int right = 0; right < s.length(); right++) {
            char c = s.charAt(right);
            
            // 如果字符已存在且在当前窗口内,移动左指针
            if (charMap.containsKey(c) && charMap.get(c) >= left) {
                left = charMap.get(c) + 1;
            }
            
            // 更新字符位置
            charMap.put(c, right);
            
            // 更新最大长度
            maxLength = Math.max(maxLength, right - left + 1);
        }
        
        return maxLength;
    }
}
时间复杂度:O(n)
空间复杂度:O(min(m,n))
算法思路: 使用滑动窗口算法解决无重复字符的最长子串问题。 核心思想: 1. 使用左右指针维护一个不包含重复字符的窗口 2. 右指针扩展窗口,遇到重复字符时左指针收缩 3. 使用哈希表/Set记录窗口内字符的出现位置 4. 实时更新最大长度 复杂度分析: - 时间复杂度:O(n),每个字符最多被访问两次(左指针和右指针各一次) - 空间复杂度:O(min(m,n)),其中m是字符集的大小,n是字符串的长度