方法一二判断相等的方法还是空间换时间,维护一个长度128的flag的bool数组(涵盖ascll表),访问一次数组元素置true,二次访问则说明有重复元素。
方法一:
暴力
时间复杂度O(n^3)
最长的测试用例超时
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int length=s.size();
bool re=true;
for(int i=length;i>=2;i--)
{
for(int j=0;j<=length-i;j++)
{
re=true;
bool flag[26]={false};
int temp;
for(int k=j;k<j+i;k++)
{
temp=int(s[k])-97;
if(flag[temp]==true)
{
re=false;
break;
}
else
{
flag[temp]=true;
}
}
if(re)
{
return i;
}
}
}
return 1;
}
};
方法二:
扫描,时间复杂度O(n^2),可以过全部用例,但是还是比较慢,不满意。
大体思路:从头开始扫描,遇到重复字符就将初始的位置+1,后来想优化一下,类似kmp的思路,就是维护一个二维数组,【x】【0】记录是否访问,【x】【1】记录位置,以后x元素重复了可以直接从【x】【1】开始再找,相当于多向前走了几步,而不是一步一步走。按理来说,这样写时间复杂度是O(n),但是可能访问二维数组比一维数组慢,不但没有变快反而变慢了。都把代码贴出来。
原始版
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int length=s.size();
if(length==0)
{
return 0;
}
int re=1;
int temp;
int dis=0;
for(int i=0;i<length;i=i+1)
{
bool flag[128]={false};
dis=0;
for(int j=i;j<length;j++)
{
temp=int(s[j]);
if(flag[temp]==true)
{
break;
}
else
{
flag[temp]=true;
}
dis++;
}
if(dis>re)
{
re=dis;
}
}
return re;
}
};
“优化版”
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int length=s.size();
if(length==0)
{
return 0;
}
int re=1;
int temp;
int dis=0;
int a=0;
int ahead=0;
// string str="pwwkew";
for(int i=0;i<length;i=ahead)
{
int flag[128][2]={0};
ahead=i+1;
dis=0;
for(int j=i;j<length;j++)
{
temp=int(s[j]);
if(flag[temp][0]==1)
{
ahead=flag[temp][1]+1;
break;
}
else
{
flag[temp][0]=1;
flag[temp][1]=j;
}
dis++;
}
if(dis>re)
{
re=dis;
}
}
return re;
}
};
方法三:
滑动窗口
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int ssize=s.size();
if(ssize==0)
return 0;
int start(0),re(0),length(0);
char temp;
for(int i=0;i<ssize;i++)
{
temp=s[i];
length=i-start;
for(int j=start;j<i;j++)
{
if(s[j]==temp)
{
start=j+1;
length=i-start;
}
}
length++;
if(length>re)
{
re=length;
}
}
return re;
}
};
方法四
哈希存储出现重复的字符最后一次出现的位置。和我方法二中企图用二维数组实现一个思路,但是hash快多了。复杂度 O(n)
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
//s[start,end) 前面包含 后面不包含
int start(0), end(0), length(0), result(0);
int sSize = int(s.size());
unordered_map<char, int> hash;
while (end < sSize)
{
char tmpChar = s[end];
//仅当s[start,end) 中存在s[end]时更新start
if (hash.find(tmpChar) != hash.end() && hash[tmpChar] >= start)
{
start = hash[tmpChar] + 1;
length = end - start;
}
hash[tmpChar] = end;
end++;
length++;
result = max(result, length);
}
return result;
}
};