3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解题思路
- 思路:双指针之滑动窗口思想
- 集合unordererd_set(特点:不含重复元素,且不自动排序,底层为哈希表存取快O(1))
- 双指针left和right表示窗口左侧和右侧,初始均指向字符串首处
- right++ 直到遇到已在set中的字符:left移动到字符串中该字符的后一位处,set中删除从left到该位置的元素
如abcdecf,left在a
处,right在第二个c
处发现有重复字符c,遍历a到第二个c中找到中间重复的那个c,窗口左端指针left移动到其后的位置d处 - 记录不含重复字符的最大长度maxAns,更新
- 知识点:
- unordererd_set
- 双指针left、right
- 记录最大值maxAns
- 易错点
- while:left移动到window中s[right]的下一个位置,不是if(易错)
- 复杂度
- 时间:O(N),N表示字符串的长度,左右指针分别遍历字符串一次
- 空间:O(M) M表示字符集的大小,即不同的字符的个数
//无重复的最长子串
class Solution {
public:
//滑动窗口
int lengthOfLongestSubstring(string s) {
unordered_set<char> window;//窗口:不含重复字符
int left, right;
int maxAns = 0;
for(left=0, right=0; right<s.size(); ++right){
while(window.find(s[right])!=window.end()){//注意是while:left移动到window中s[right]的下一个位置
window.erase(s[left]);
++left;
}
maxAns = max(maxAns, right-left+1);
window.insert(s[right]);
}
return maxAns;
}
};
执行用时:56 ms, 在所有 C++ 提交中击败了41.65% 的用户
内存消耗:11 MB, 在所有 C++ 提交中击败了26.94% 的用户
- Leetcode滑动窗口题
- 3.无重复字符的最长子串
- 30.串联所有单词的子串
- 76.最小覆盖子串
- 159.至多包含两个不同字符的最长子串
- 209.长度最小的子数组
- 239.滑动窗口最大值
- 567.字符串的排列
- 632.最小区间
- 727.最小窗口子序列