给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
思路
一次遍历字符串,记录下每种字母出现的最新索引,当遍历的字母上一次出现的索引大于不重复子串的起始索引时,说明该字母在当前子串重复。不重复子串的长度丢等于,重复字母上一次的索引 - 子串起始索引 + 1 。
下一个子串的起始设置为重复字母的后一位。
最后更新字母对应的索引。
这里用数组来存放字母的索引应该更快。
int lengthOfLongestSubstring(string s) {
//因为子串要求不能出现重复字母,因此考虑用一个map,保存每个字母最新索引
//还要使用一个变量start 保存子串开始位置索引
int start = 0;
int res = 0;
map<char, int> ch;
int s_len = s.size();
for(int i = 0; i < s_len; ++i)
{
if(ch.find(s[i]) != ch.end())
{
int index = ch[s[i]];
if(index >= start)
{
// cout << "index " << index << endl;
//出现重复字母
res = max(res, i - start);
// cout <<i << " " << res << endl;
start = index + 1; //从重复字母下一个开始计算长度
}
}
ch[s[i]] = i; //更新索引
}
res = max(res, s_len - start); //遍历完计算最后的不重复子串的长度
return res;
}