leetcode:3. 无重复字符的最长子串
题目
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例:
输入: s = "abcabcbb"输出: 3解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: s = "bbbbb"输出: 1解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: s = "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解答 & 代码
滑动窗口:(不过本题不能再直接套滑动窗口的框架了)
class Solution {public:int lengthOfLongestSubstring(string s) {// 哈希表,记录窗口中出现的字符及下标,key=字符, val=下标unordered_map<char, int> window;int left = 0;int right = 0;int maxLen = 0;// 滑动窗口 [left, right)while(right < s.size()){char ch = s[right]; // 将要添加到窗口的字符++right; // 右指针右移,窗口扩增// 如果该字符不在窗口中,则将<该字符,下标>加入窗口的哈希表// 判断窗口在哈希表中有两种可能性:// a. 哈希表中不存在该字符; b. 该字符对应的下标小于左边界if(window.find(ch) == window.end() || window[ch] < left)window[ch] = right - 1;// 如果该字符在窗口中已经存在,则:else{// 用当前窗口长度 -1 (去掉最后这个重复字符)和最长子串长度比较,更新最长子串长度maxLen = max(maxLen, right - left - 1);// 左指针右移,直接跳到该字符上一次出现的位置之后,使得窗口内无重复字符left = window[ch] + 1;// 更新哈希表中这个重复字符的下标window[ch] = right - 1;}}// 最后还要再更新一下 maxLen// 否则 eg. 字符串" "就错误地输出 0,实际应为 1maxLen = max(maxLen, right - left);return maxLen;}};
复杂度分析:设字符串 s 长为 N,包含 C 个不同的字符
- 时间复杂度 O(N):最坏情况下,字符串
s的每个字符分别被左、右指针遍历一次 - 空间复杂度 O(C):最坏情况下,哈希表占的空间 = 字符串
s中不同字符的种数 C
执行结果:
执行结果:通过执行用时:8 ms, 在所有 C++ 提交中击败了 86.49% 的用户内存消耗:8.1 MB, 在所有 C++ 提交中击败了67.61% 的用户
