题目链接: https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
Description
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.
解题思路
题意为找到最长的无重复字符的子串的长度。
因为共有 256 种不同的字符,所以可以用一个数组来记录每一个字符最后一次出现的下标。用变量 start
来记录当前子串第一个字符的下标,遍历字符串,若发现字符 s[i]
对应的最后一次出现的下标大于等于 start
,即表示 s[i]
在该子串中已经出现过,则当前子串的下标区间为 [start, i - 1]
,更新长度记录。并且,新的子串起始位置应该为 s[i]
上次出现的下标后一个位置,这样才能保证最长这一个条件。
另外,由于更新长度记录是在遍历中进行的,因此若最长子串包含最后一个字符,在遍历过程中就不能更新该长度记录,所以要在遍历外边再加一个长度记录更新。
举个例子,s = "abac"
,记录字符最后一次出现下标的数组为 alpha[256]
,'a'
的 ascii 码为 97。
i == 0, s[i] == 'a'
:start = 0, alpha[97] = 0
,子串为"a"
。i == 1, s[i] == 'b'
:alpha[98] = 1
,子串为"ab"
。i == 2, s[i] == 'a'
:alpha[97] == 0 >= start
=> 当前子串"ab"
已经有'a'
存在,更新长度记录为2
,并且应该从'b'
开始下一个子串,所以start = alpha[97] + 1
,即为1
。alpha[97] = 2
,子串为"ba"
。i == 3, s[i] == 'c'
:alpha[99] = 3
,子串为"bac"
,更新长度记录为3
。
Code
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> alpha(256, -1);
int res = 0, start = 0;
for (int i = 0; i < s.size(); ++i) {
if (alpha[s[i]] >= start) {
res = max(i - start, res);
start = alpha[s[i]] + 1;
}
alpha[s[i]] = i;
}
res = max((int)(s.size() - start), res);
return res;
}
};