LeetCode - 3. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters.
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.
题目意思就是找出连续的,没有重复字符的,最长子串的长度,“pwwkew” 这个例子中,“wke” 和 “kew” 都是最长子串,不过找到出目前最长子串为 3 的时候,就不需要去判断 “kew” 了,因为就算是不重复的,最长也只是3,和现在的一样。
这种一个串的题,最容易想到的就是用两个哨兵从两边夹逼,但是对这道题好像不太适用,第二种方法就是用一个尺子从左往右滑,不断调整尺子大小,滑到最右边就完成算法,也就是滑动窗口,Sliding Window,AC代码如下:
int lengthOfLongestSubstring(string s) {
const int len = s.length();
if(len <= 1) return len;
int l = 0, r = 0, max_len = 1;
// 记录滑动窗口中每个字符所在位置, ascii码 0-127
vector<int> ids(128, -1);
while(r != len) {
const int sr = s[r]; // 转成 ascii 码
if(ids[sr] != -1) {
// 之前的 ids[t] 及以前位置弹出
for(int i = l; i < ids[sr]; ++i)
ids[s[i]] = -1;
l = ids[sr] + 1;
}
else
max_len = max(max_len, r - l + 1);
ids[sr] = r++; // 不能 ids[s[r]] = r++; !!!
}
return max_len;
}
值得注意的是:ids[s[r]] = r++;
这个是C++未定义行为,就是执行顺序是不一定的,有可能对,有可能不对!!!所以一个表达式里尽量不要有 ++ 或者 --,尽量保证表达式中只有一个这个变量,否则很可能有问题。
比如 a[b[i]] = i++;
这样写了,或者 int a = i++ + i++;
,vs 也会提示 "Unsequenced modification and access to ‘i’"。