无重复字符的最长子串
theme:给定一个字符串,求无重复字符的最长子串长度,注意子串是连续的(子序列可以不连续)。
solution:提供两种做法(本质是一样的)
(1)dp:用dp[i]表示以第i个字符结尾的无重复字符的最长子串长度,则最终结果遍历找最大值即可。转移方程:当s[i]==s[i-1]时,dp[i]=1,否则从i-1向前遍历dp[i-1]的长度的字符判断是否与s[i]相同,因为dp[i-1]代表这dp[i-1]个字符互不相同,而其中一个与前一个字符重复。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int l=s.length();
if(!l)
return 0;
int dp[l+5];
dp[0]=1;
for(int i=1; i<l; ++i)
if(s[i]==s[i-1])
dp[i]=1;
else{
dp[i]=dp[i-1]+1;
for(int j=i-2; j>=i-dp[i-1]; --j)
if(s[i]==s[j])
{
dp[i]=i-j;
break;
}
}
// far(i,l)
// cout<<dp[i]<<" ";
int ans=*max_element(dp,dp+l);
return ans;
}
};
(2)用字典记录某个第一次出现的下标,用变量i表示其后有与它相同字串的最大下标,则遍历字符
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
st = {}
i, ans = 0, 0
for j in range(len(s)):
if s[j] in st:
i = max(st[s[j]], i)
ans = max(ans, j - i + 1)
st[s[j]] = j + 1
return ans;