3. 无重复字符的最长子串
题目描述
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
题解
思路:从第一个字符开始,不断扩大子串。如果出现重复,则从重复的字符处重新开始扩大子串。
滑动窗口
- 哈希表存储字符,用于判断是否有重复字符出现。
存在问题:算法执行时间非常长(大于600 ms)
可能原因:
- 哈希表被反复清空
class Solution { public: int lengthOfLongestSubstring(string s) { unordered_map<char, int> umap; int len = 0; int max = 0; for (int i = 0; i < s.length(); i++) { if (umap.find(s[i]) == umap.end()) { umap.insert({s[i], len++}); } else { umap.clear(); max = max > len ? max : len; i-=len; // 从失败的字符重新开始匹配。 len = 0; } } max = max > len ? max : len; // 处理最长子串在结尾的情况 return max; } };
[!NOTE]
unordered_map
插入的顺序是{value,index}
。find
查找的时候,查找value
值。如果找到,则返回key
键;如果没有找到,则返回.end()
末尾。
滑动窗口优化
此解法参考Krahets。耗费时间10 ms,速度提升近60倍。因此,哈希表的清空.clear()
是一个非常耗费时间的过程。
核心思想:避免清空哈希表,保持哈希表内元素下标最新。
class Solution { public: int lengthOfLongestSubstringImproved(string s) { unordered_map<char, int> umap; int left = -1, len = 0, maxLen; // left:最长无重复字符子串的最右端。起始情况最长字符为空,所以left为-1 for (int right = 0; right < s.size(); right++) { // right:指向被判断的字符 if (umap.find(s[right]) != umap.end()) // 在哈希表中,被查找到 left = max(left, umap.find(s[right])->second); // 更新左指针。反例abba,足以解释为什么要用max umap[s[right]] = right; // 哈希表记录。保持哈希表中的元素始终是不重复的,且坐标都是最新的,相当于窗口在滑动 maxLen = max(len, right - left); // 更新结果 } return maxLen; } };
难理解点
left = max(left, umap.find(s[right])->second)
举例,输入字符串abba。
当right指向第二个b时,出现重复。此时,left = -1
,umap.find(s[right])->second) = 2
。left就直接移动到了第二个b的位置,即从重复字符开始重新匹配。注意,此时哈希表中的a的下标仍然是0。
当right指向第二个a时,出现重复。此时,left = 2
,umap.find(s[right])->second) = 0
,即重复字符不是left指向的字符,此时left就不想要移动。
umap[s[right]] = right
该方式:
- 如果键值对不存在,则插入
- 如果键值对存在,则修改值对应的键
maxLen = max(len, right - left)
求两个范围内的个数,一般情况下需要+1,即其中一个端点。
但是,理清left和right的含义。left:最长无重复字符子串的最右端;right:被判断的字符,即最长不重复子串的在一个,相当于已经+1了。
本文作者:顾子郤
本文链接:https://www.cnblogs.com/coder-shane/p/18441581
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步