两种方法,一种是滑动窗口法,一种是利用哈希图。
滑动窗口法:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> m(128, 0); //ASCII码范围:0-127
int ans = 0;
int i = 0;
for (int j = 0; j < s.size(); j++) {
if(m[s[j]]!=0) //当遇见重复的字符
{
i = max(i, m[s[j]]);
}
//没有遇见重复字符
m[s[j]] = j + 1;
ans = max(ans, j - i + 1);
}
return ans;
}
};
其实原理也是哈希图。
哈希图:
//start和end分别是滑动窗口的头和尾
int start = 0, end = 0, length = 0, result = 0;
unordered_map<char, int> hash;
while (end < s.size())
{
char tmpChar = s[end];
//仅当s[start,end) 中存在s[end]时更新start
//当出现重复符号
if (hash.find(tmpChar) != hash.end() && hash[tmpChar] >= start)
//hash[tmpChar] >= start什么意思,我都理解是:hash[tmpChar] 是由上一次while循环end赋值,
//而end和start都是滑动窗口的尾和头,所以必须大于等于,不然当 执行length = end - start;时,length的值会小于0
{
start = hash[tmpChar] + 1;
length = end - start;
}
//没有重复符号
hash[tmpChar] = end;
end++;
length++;
result = max(result, length);
}
return result;
}
对于 find() 函数,查找以 key 为键的键值对,如果找到,则返回一个指向该键值对的正向迭代器;反之,则返回一个指向容器中最后一个键值对之后位置的迭代器(如果 end() 方法 返回的迭代器)。