自己没想出来, 代码来自别人的博客, 但是找不到出处了…
代码实现
int longestSubstring(string str)
{
//利用哈希的思想,key是每一个字符,value是其对应的下标
// 存储上一个重复字符的位置
int* lastPosition = new int[256];
//初始化,首字符之前没有与其重复的字符,都为-1
for (int i = 0; i < 256; i++)
{
lastPosition[i] = -1;
}
int previous = -1; //记录上一个不重复子串的终点
int current = 0; //记录当前不重复子串长度
int maxLength = 0; //记录最大不重复子串长度
int n = str.size();
for (int i = 0; i < n; i++)
{
//碰到重复字符previous更改为该重复字符的位置
previous = max(previous, lastPosition[str[i]]);
//本次子串长度
current = i - previous;
maxLength = max(current, maxLength);
//更新该字符对应的下标
lastPosition[str[i]] = i;
}
return maxLength;
}
大概流程
- 假设有字符串
aabdcdde
, 那么我们一次遍历,previous
记录上一个不重复子串的终点为 -1, 得到首字符组成的子串长度为 1, 然后更新lastPosition['a']
的值为 0 - 然后遍历到 i = 1 时, a 此时重复出现在当前子串中,
previous
更新为其上一出现位置的下标 (即 0), 计算的当前不重复子串长度为 1,previous
值变为 0,lastPosition['a']
的值更新为 1, - 这样一直遍历直到碰到第二个
d
, 即遇到重复字符了, 遇到他之前我们已经记录了之前不重复子串的长度, 即abdc
, 遇到他之后previous
更新为其上一次出现的位置, 然后计算从previous
到其当前位置的子串长度, 和maxLength
比较 - 循环上述过程直到遍历完字符串,
maxLength
中就是最长不重复子串长度