问题描述
问题分析
题目比较短,但是要确保理解题意。我是这样想的:既然要求出无重复字符的最长子串,我就拿题目给的例子来模拟的一下我的想法。当以第一个字母a开头的时候,有a,ab,abc。abca这个就不符合题意了,当以第二个字母b开头的时候,有b,bc,bca。bcab这个也不符合题意了,依次类推直到最后一个字符。根据这个想法可以得到以下几点理解:
- 可以求出以每个字符开头的最长子串,然后在这些最长子串中取出一个最大的,就是满足题意得解。
- 既然是每个字符开头,就要遍历,遍历到当前字符得时候如何知道当前字符是否是已经遍历过的字符里面有的?这里就是典型的重复和查找问题,可以用哈希表查找,可以用数组标记元素出现得次数,数组得下标是元素得值,数组得值是元素出现得次数
- 既然遍历了,而且需要统计字符得长度,很明显需要两个变量,一个变量l需要指向当前字符串得头子符,还需要一个变量r来遍历当前字符,直到发现重复的或者遍历结束为止。注意:这里有一个问题,当遍历到重复得时候,是否需要r回退到l得位置,然后l指向不同得头子符,然后r再继续遍历?这里可以不用,因为在重复得字符之间,要么没有字符要么就是必然不重复得字符。
- 根据123可以得到,可以使用滑动窗口来求解这个题目。
代码表述
思路对了,写完最好模拟以下,防止细节问题出错。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
//
int l=0;//左指针
int n=s.size();
//先用数组
vector<int>a(256,0);
int res=0;
for(int r=0;r<n;r++){//右指针
while(a[s[r]]>0){ //滑动窗口缩小得条件
a[s[l]]--;//缩小窗口之前先将元素剔除
l++;//然后开始缩小窗口
}
a[s[r]]++;//满足题意就一直扩大窗口
res=max(res,r-l+1);//每次扩大窗口都将当前窗口得值记录下来,因为可能下一次就开始缩小窗口了。
}
return res;
}
};
复杂度分析
时间复杂度:O(N),N是字符串得长度,两个指针会分别遍历字符串一次
空间复杂度:O(字符得个数),这里我觉得就是数组中会统计多少字符。