力扣算法题Day3
给定一个字符串 s
,请你找出其中不含有重复字符的 最长 子串 的长度。
示例 1:
1 2 3
| 输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
|
示例 2:
1 2 3
| 输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
|
示例 3:
1 2 3 4
| 输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
|
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
解题思路:
首先要用一个max去记录无重复字符的最长子串的长度,初始化为0。
然后定义个map用来装无重复字符的最长子串。
然后开始正式遍历,按照顺序读取字符串s的每个字符,装入map中,如果map中已经有重复字符,则需要先将map中出现重复字符的位置以及这个重复字符位置之前的字符都要删掉(因为要获取无重复字符的最长子串,这里要结合示例1和示例3理解一下),然后再把当前字符装入map中。
每读取一个字符就需要判断当前无重复字符的子串的长度是否大于max,如果大于则更新max为当前无重复字符的子串的长度。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class Solution { public: int lengthOfLongestSubstring(string s) { int max = 0; // 记录最大字串长度 std::map<char, int> myMap; for (int i = 0; i < s.size(); i++) { // 循环遍历s // std::cout << "=======================" << std::endl; // std::cout << "读第" << i << "个字符" << s[i] << std::endl; // //读取第i个字符 if (myMap.find(s[i]) != myMap.end()) { // 判断是否出现重复字符 // cout << myMap[s[i]] << "的位置重复" << endl; // 输出当前map方便查看 // cout << "当前map:" << endl; // for (std::map<char, int>::iterator it = myMap.begin(); // it != myMap.end(); ++it) { // std::cout << it->first << " is " << it->second << // std::endl; // } // 如果map中出现重复字符的位置以及之前的字符都要删掉 for (std::map<char, int>::iterator it = myMap.begin(); it != myMap.end();) { if (it->second < myMap[s[i]]) { it=myMap.erase(it); } else ++it; } myMap.erase(s[i]); // 将新的字符插入 // cout << "添加新的" << s[i] << "位置为" << i << endl; myMap[s[i]] = i; } else { // 如果没有出现重复字符,则直接插入map myMap[s[i]] = i; } // 展示读取完一次字符后执行完操作的map // cout << i << "次读取字符后map:" << endl; // for (std::map<char, int>::iterator it = myMap.begin(); // it != myMap.end(); ++it) { // std::cout << it->first << " is " << it->second << std::endl; // } // 更新max if (myMap.size() > max) { max = myMap.size(); } } return max; } };
|