Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
Solution
采用滑动窗口的思想,在窗口内,没有重复的元素。
判断窗口外的下一个元素在窗口内是否由重复元素,
如果没有,则扩展窗口,包含下一个元素,并更新最大字串长度。
如果有,则更新窗口起始位置为窗口内重复元素的下一个元素位置(窗口起始位置可以通过这种方法实现跳跃前进,而不需要逐个向前移动)。
优化
下面的实现中,是用遍历的方法判断窗口内是否有重复元素,时间复杂度是O(n),可以做的优化,就是通过判断hash表记录窗口内的元素,让查找的时间复杂度提高到O(1)。
Code
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if (s.empty())
{
return 0;
}
// 滑动窗口开始位置
int subStrStartIndex = 0;
// 滑动窗口结束位置
int subStrEndIndex = 0;
// 最大滑动窗口长度
int maxSubStrLength = 1;
// 滑动窗口外的下一个元素位置
int subStrNextIndex = 0;
while (subStrEndIndex < s.length() - 1)
{
if (++subStrNextIndex == s.length())
{
break;
}
int repeatIndex = findRepeatCharacter(s, subStrStartIndex,
subStrEndIndex,
subStrNextIndex);
if (repeatIndex == -1)
{
// there is no repeat charactor in pre substring
subStrEndIndex = subStrNextIndex;
int curSubStrLength = subStrEndIndex - subStrStartIndex + 1;
if (maxSubStrLength < curSubStrLength)
{
maxSubStrLength = curSubStrLength;
}
}
else
{
subStrStartIndex = repeatIndex + 1;
subStrEndIndex = subStrNextIndex;
}
}
return maxSubStrLength;
}
private:
int findRepeatCharacter(const std::string& s,
int startIndex,
int endIndex,
int nextIndex)
{
for (int searchIndex = startIndex;
searchIndex <= endIndex;
++searchIndex)
{
if (s[searchIndex] == s[nextIndex])
{
return searchIndex;
}
}
return -1;
}
};