题目来源:LeetCode 3:无重复字符的最长子串
问题抽象: 给定一个字符串 s(长度 ≥ 0),要求找到其所有子串中 不包含重复字符 的最长子串的长度,满足以下核心需求:
-
子串定义:
- 子串必须是字符串中 连续的字符序列;
- 子串中所有字符必须 唯一(无重复字符)。
-
计算约束:
- 时间复杂度 O(n)(n 为字符串长度),空间复杂度 O(min(m, n))(m 为字符集大小);
- 需通过 滑动窗口 和 哈希映射 实现:
- 维护窗口 [start, end],记录字符最后出现位置;
- 遇到重复字符时,移动 start 到重复字符的下一个位置。
-
边界处理:
- 空字符串 → 返回 0;
- 全唯一字符 → 返回字符串长度;
- 特殊用例:
s="abcabcbb"→ 输出 3(“abc”);s="bbbbb"→ 输出 1(“b”);s="pwwkew"→ 输出 3(“wke” 或 “kew”)。
输入:字符串 s。
输出:整数值(最长无重复字符子串的长度)。
解题思路
要找到字符串中不含有重复字符的最长子串,可以使用滑动窗口(双指针) 的方法。具体思路如下:
-
初始化:使用两个指针
start和end表示当前窗口的起始和结束位置,初始时两者都为0。同时,使用一个数组lastOccurrence记录每个字符最后一次出现的位置(初始值为-1)。 -
遍历字符串:移动
end指针遍历每个字符:- 如果当前字符在
lastOccurrence中记录的位置大于等于start,说明该字符在当前窗口内重复出现,需要移动start指针到该字符上次出现位置的下一位。 - 更新当前字符的最后出现位置为当前
end指针的位置。 - 计算当前窗口的长度(
end - start + 1),并更新最大长度。
- 如果当前字符在
-
返回结果:遍历结束后,返回记录的最大长度。
本方法通过一次遍历即可完成,时间复杂度为 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。 - 滑动窗口:通过
start和end指针维护当前无重复字符的子串窗口。 - 更新策略:当遇到重复字符时,将
start指针移动到重复字符上次出现位置的下一位,确保窗口内无重复字符。 - 效率:该算法只需遍历字符串一次,时间复杂度为 O(n),空间复杂度为 O(1)(固定大小的数组)。
提交详情(执行用时、内存消耗)


2335

被折叠的 条评论
为什么被折叠?



