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 subsequenceand not a substring.
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int max=0,i=0,j=0;
map<char,int> p;
while (i<s.size()&&j<s.size()){
if(p.find(s[i])==p.end()){
p[s[i]]=i++;
max=(max>i-j)?max:i-j;
}
else
p.erase(s[j++]);
}
return max;
}
};
补习知识:
1、map的初始化方法(已总结)
2、关联容器的find()函数
map.find[key]
若[ ]内的待检测关键字在map里,则返回一个迭代器,该迭代器指向map中key跟待检测关键字相同的元素(pair型的);若待检测关键字不在map里,则返回尾后迭代器:map.end();
3、关联容器的erase函数
(1)c.erase(k):从c中删除一个关键字为k的元素,返回一个size_type值,指出删除元素的数量;
(2)c.erase(p):从c中删除迭代器p指定的元素,返回一个指向p之后元素的迭代器;
(3)c.erase(b,e):从c中删除迭代器b和e所表示范围中的元素,返回e;
Solution的大致思路:
建立一个map,key为字符,value为key在s中对应的下标,即i。用直接赋值的方式将s中的每个字符初始化给map,用map的find()函数来检测新赋值的元素的关键字是否重复,如果重复,用map的erase()函数将map中开头的元素删掉,j为map中保存的首元素在s中的下标,这样删除的一直是重复字符的第一个;如果没有重复,把s中的该元素赋值给map,并检测max和i-j的长度,i-j就是没有重复的字符串的尾元素的下标减去首元素的下标,即未重复的字符串的长度。max是所有出现过的未重复字符串长度的最大值,一直与新的i-j进行比较,因为最后要的是最长未重复字符串的长度。代码中的注释如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
/* max是出现过的未重复字符串的长度
i是s中初始化给map的元素的下标
j是map中未重复字符串的首元素对应的value,随着重复元素的出现而不断向后移动(j++)
*/
int max = 0, i = 0, j = 0;
map<char, int> p;
while (i<s.size() && j<s.size()){
//用find函数检测是否有重复元素,若没有,则返回尾后迭代器end()
if (p.find(s[i]) == p.end()){
p[s[i]] = i++;//将s中的元素初始化给p,并向后移动s的下标
max = (max>i - j) ? max : i - j;//max与重复字符串的长度进行比较,选最大的保存
}
else
p.erase(s[j++]);//用erase删除map中重复字符串的首元素(重复字符的第一个),并将map首元素在s中对应的下标向后移动
}
return max;
}
};