题目:3. 无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。
示例 1:
1 | 输入: s = "abcabcbb" |
示例 2:
1 | 输入: s = "bbbbb" |
示例 3:
1 | 输入: s = "pwwkew" |
提示:
0 <= s.length <= 5 * 104s由英文字母、数字、符号和空格组成
题解1 执行用时119ms 消耗内存10.6MB
思路:依次递增地枚举子串的起始位置
1 | class Solution { |
题解2 执行用时18ms 消耗内存14.16MB
思想:滑动窗口
以示例一中的字符串 abcabcbb 为例,找出从每一个字符开始的,不包含重复字符的最长子串,那么其中最长的那个字符串即为答案。对于示例一中的字符串,我们列举出这些结果,其中括号中表示选中的字符以及最长的字符串:
以 (a)bcabcbb 开始的最长字符串为 (abc)abcbb;
以 a(b)cabcbb 开始的最长字符串为 a(bca)bcbb;
以 ab(c)abcbb 开始的最长字符串为 ab(cab)cbb;
以 abc(a)bcbb 开始的最长字符串为 abc(abc)bb;
以 abca(b)cbb 开始的最长字符串为 abca(bc)bb;
以 abcab(c)bb 开始的最长字符串为 abcab(cb)b;
以 abcabc(b)b 开始的最长字符串为 abcabc(b)b;
以 abcabcb(b) 开始的最长字符串为 abcabcb(b)。
依次递增地枚举子串的起始位置,那么子串的结束位置也是递增的!这里的原因在于,假设我们选择字符串中的第 k 个字符作为起始位置,并且得到了不包含重复字符的最长子串的结束位置为 r
k。那么当我们选择第 k+1 个字符作为起始位置时,首先从 k+1 到 rk的字符显然是不重复的,并且由于少了原本的第 k 个字符,我们可以尝试继续增大 rk,直到右侧出现了重复字符为止。
1 | class Solution { |
总结:
- 题解2时间复杂度:O(N),其中 N 是字符串的长度。左指针和右指针分别会遍历整个字符串一次。
- 题解2,只需要occ.erase(s[i - 1]);就行,因为s[i - 1]后面的可以复用。