问题描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
解题报告
滑动窗口
这道题方法有好几种,这里只讨论 滑动窗口方法。
- 移动窗口的右边界时,更新窗口内每个字符出现的次数【使用 桶 来装每个字符出现次数】。
- 当窗口内某个字符出现超过一次时,说明出现了重复字符,此时需要移动左边界
- 移动左边界时,更新窗口内每个字符出现的次数。
- 左右边界稳定时,更新最长子串
其他解法
动态规划
参考Leetcode 面试题48. 最长不含重复字符的子字符串【动态规划】
纯数据结构
记录已经遍历过的字符出现的位置,始终记录当前的最长子串。
- 出现重复字符时,更新重复字符新的位置。
实现代码
滑动窗口实现
class Solution{
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> window;
int left = 0, right = 0;
int res = 0; // 记录结果
while (right < s.size()) {
char c = s[right];
right++;
// 进行窗口内数据的一系列更新
window[c]++;
// 判断左侧窗口是否要收缩
while (window[c] > 1) {
char d = s[left];
left++;
// 进行窗口内数据的一系列更新
window[d]--;
}
// 在这里更新答案
res = max(res, right - left);
}
return res;
}
// 作者:labuladong
// 链接:https://leetcode-cn.com/problems/permutation-in-string/solution/wo-xie-liao-yi-shou-shi-ba-suo-you-hua-dong-chuang/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
};
其他解法实现
动态规划
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n=s.size(),ans=1,flag=0,i,j,p=0;
if(n==0) return 0;
vector<int>dp(n,1);
for(i=1;i<n;i++){
for(j=i-1;j>=p;j--){
if(s[i]==s[j]){
flag=1;
break;
}
}
if(!flag)
dp[i]=dp[i-1]+1;
else{
dp[i]=i-j;
p=j;
flag=0;
}
ans=max(ans,dp[i]);
}
return ans;
}
};
纯数据结构
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char,int>mp;
int ans=0;
for(int i=0,j=0;j<s.size();j++){
if(mp.find(s[j])!=mp.end()){
i=max(i, mp[s[j]]+1);
}
mp[s[j]]=j;
ans=max(ans,j-i+1);
}
return ans;
}
};
参考资料
[1] Leetcode 3.无重复字符的最长子串
[2] 题解区:labuladong