给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 (请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串。)
错误示范:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(!s.size())
return 0;
vector<int> num;
myfun(s,num);
int maxnum=1;
for(int i=0;i<num.size();i++)
{
maxnum=max(maxnum,num[i]);
}
return maxnum;
}
private:
void myfun(string s,vector<int> &ans)
{
unordered_map<char,int> a;
int count=0;
for(int i=0;i<s.size();i++)
{
if(a.find(s[i])!=a.end())
{
ans.push_back(count);
count=0;
int flag=a[s[i]];
string s1=s.substr(flag+1); //从重复数字的后一个找起
a.clear();
myfun(s1,ans);
}
else{
count++;
a.emplace(s[i],i); }
}
ans.push_back(count);
return;
}
};
错误原因:太暴力了,遇到大量重复字符时会导致重复计算,从而导致超时。
正确且不超时的解答:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(!s.size()) return 0;
unordered_map<char,int> a; //存储字符及其对应地址
int ans=0;
int flag=0;//用来找重复的字符,初始为0
for(int i=0;i<s.size();i++)
{
if(a.find(s[i])!=a.end()) //在哈希表中找到,则更新flag
{
//flag=a[s[i]]+1; 错误,可能导致flag左移,窗口字符重复
flag=max(flag,a[s[i]]+1);
}
a[s[i]]=i;//及时更新哈希表中字符的最新位置
ans=max(ans,i-flag+1);
}
return ans;
}
};