原题
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
思路 (双指针算法)
假设字符串s
中从j
到i
中不包含重复字符
实现:当i
往后走时,先将字符统计一下出现次数,如果当前字符s[i]
的在集合中出现次数 > 1,那么j
就需要走到能把s[i]
相除到出现次数为1的位置,然后统计一下从j
到i
的长度 res=max(res, i - j + 1)
问题:当i
往后走,j
会不会往前走呢?答案是否定的,如果i
往后走到i'
,j
往前走到j'
,根据上面假设出发,从j'
到i'
中不包含重复字符,由于答案保证从j
到i
是也不包含重复字符的,那么从j'
到i
也一定不存在重复字符,那就存在矛盾了。所以j
要么就是原地不动,要么就是往后走
题解
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> map; // 记录字母出现次数
int res = 0; //无重复字符的最长子串的长度
for (int i = 0, j = 0; i < s.size(); i ++ ) {
map[s[i]] ++; // 统计当前字母出现次数
while (map[s[i]] > 1) map[s[j ++ ]] -- ; //当字母s[i]出现了两次,j一边走一边删除不包含在区间内出现字符的次数,直到删除到s[i]只出现一次为止
res = max(res, i - j + 1);
}
return res;
}
};