这道题是leetcode第三题,leetcode把它分到了medium的难度,题目如下:
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
对于这道题,有三种解法:
1、穷举法
步骤一:令sunstring开始的index为 i ,最后一个字符的index为 j , 0<=i<j<=n ;
步骤二:然后从 i=0 开始扫描整个string,直到遇到一个 s[j] 使得 [i,j] 的substring最大;
步骤三: i++ ,重复步骤二。最终通过比较会找到一个最长的substring,从而达到题目要求。
这种解法是最不费脑细胞的,但是当你把
代码提交的时候,你会发现真的是特别慢啊,都是耗时都属于倒数水平了。于是就有了以下的两种解法。
2、滑动窗口
步骤一:令sunstring开始的index为 i , 0<=i<j<=n ,首先从 i=0 开始找到不重复的最大substring,记录下最后一个字符的index为 j ,从而可以形成窗口 [i,j] ,可以假设目前不重复的最大substring长度为 j−i+1 ;
步骤二:滑动窗口,令窗口变成 [i+1,j+1] ,再通过 j++ 来扩大窗口大小,同时保证新的substring内没有重复的字符
步骤三:重复步骤二,最终得到最大substring的长度。
代码如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int asc[256] = {0};
int len = s.length();
if(s.length() == 1)
return 1;
int max = 0;
int i = 0, j = 1;
asc[(int)s[i]] ++;
while(i < len && j < len)
{
while(j < len)
{
if(asc[(int)s[j]] == 0)
{
asc[(int)s[j]] ++;
j ++;
}
else{
break;
}
}
if(j - i > max)
{
max = j - i ;
}
asc[(int)s[i]] --;
i ++;
}
return max;
}
};
3、对于方法二的优化
步骤一:同方法二;
步骤二:步骤一完成后,会形成一个
[i,j]
的窗口,而第
j+1
个字符正好是一个与前面字符有重复的,因此,我们跳过前面所有的元素,直接将
i
变成
j+1
;
步骤三:重复步骤二。
补充:ASCⅡ码一共有256个,前128个能在键盘上找到,后128个为键盘无法表示的。