目录
1.动态规划
先来分析一下吧。。。这题我们很容易想到,假设f(i)表示以下标i结尾的s[i]中的最长不含重复字符的子字符串,那么f(i)=f(i-1)+1是不是很容易想到?不过这里是有条件的,首先,,其次,这里面如果以s[i-1]结尾的字符串里包含s[i]的字符怎么办?我们是不是要取上次出现的相同s[i]到当前位置i的距离作为f(i)。
以下是代码:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int len=s.size();
if(len==0) return 0;
int position[128];//通过ascii码作为索引可以访问上一次出现的位置
for(int &i:position) i=-1;
int curLength=0,ans=0;
for(int i=0;i<len;++i)
{
//记录上一次的相同字母的位置
int index=position[s[i]];
//直接对curLength增一操作有两种情况
//1.第一次出现
//2.和上一次出现的相同字母之间的距离大于以i-1个字母结尾的最长长度
if(index==-1||i-index>curLength)
{
++curLength;
}
else
{
//每次等到要直接切换curLength的时候更新ans
if(curLength>ans)
{
ans=curLength;
}
curLength=i-index;
}
position[s[i]]=i;
}
//可能最后一次记录的curLength没有更新
if(curLength>ans)
{
ans=curLength;
}
return ans;
}
};
这里用position数组来实现了记录上一次出现位置的功能,即字符到位置的映射。
不过说这题是不是不大严谨,我都不知道他字符的范围一开始......
2.滑动数组
学习一下嘿嘿,直接cv:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int l=0,r,maxLen = 0;
int a[128];
//记录字符上一次出现的位置
for(int &i:a){i =-1;}
for(r = 0;r<s.length();){
//上一次出现的位置在窗口外或者没有上次出现
if(a[s[r]]==-1 || a[s[r]]<l){
a[s[r]] = r;
r++;
}else{
//出现重复,移动窗口
maxLen = max(maxLen,r-l);
l = a[s[r]]+1;
a[s[r]] = r;
r++;
}
}
maxLen = max(maxLen,r-l);
return maxLen;
}
};
感觉大同小异吧,只是解释的方法不一样,感谢大佬教我编程~