[leetcode刷题 C++] 3. Longest Substring Without Repeating Characters
-
题目
Given a string, find the length of the longest substring without repeating characters.Example 1:
Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3.
Example 2:
Input: "bbbbb" Output: 1 Explanation: The answer is "b", with the length of 1.
Example 3:
Input: "pwwkew" Output: 3 Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
-
思路
最基本的思路就是:对于字符串中的每个字符,找到从之开始的最长子字符串的长度,从而找到整个字符串的最长子字符串长度那么,怎么找从某个字符开始的最长子字符串?
- 1 直接遍历
从指定的字符开始遍历,一直到发现当前字符与之前遍历的字符相同,时间复杂度: O(n^2) - 2 滑动窗口
滑动窗口就是将 [i,j) 作为一个窗口范围,表示从字符 S[i] 开始,到 S[j-1] 这个范围内的字符都不重复。
对于字符 S[i],我们已经遍历得到了最长子字符串 Si, j-1,那么对于字符 S[i+1] 来说,Si+1,j-1 这个字符串必然是不包含重复的字符的。所以我们不需要每次都重复遍历,只需要判断第 j 个字符是否与 [i,j-1] 中的字符重复:如果不重复,将j加入这个范围,即右窗口往左移; 如果重复,将 i 增加,即窗口往右移,一直移动到与j相同的后一个字符,即将 j‘ + 1 (因为这些字符串必然比从i开始的字符串短),可以使用hash表来查询重复的字符,此时时间复杂度O(1)
- 1 直接遍历
-
O(n^3) 直接遍历
代码如下:class Solution { public: int lengthOfLongestSubstring(string s) { int n = s.length(); int begin, end, max_len = 0; for(begin = 0; begin < n; begin++) { end = begin + 1; for(end; end < n; end++) { if(foundSame(s, begin, end)) { break; } } if((end - begin) > max_len) { max_len = end - begin; } } return max_len; } int foundSame(string s, int begin, int end) { if(begin < 0 || end >= s.length()) { return 0; } for(int i = begin; i < end; i++) { if(s[i] == s[end]) return 1; } return 0; } };
-
O(n) 滑动窗口
代码如下:class Solution { public: int lengthOfLongestSubstring(string s) { unordered_map<char, int> hash_tbl; unordered_map<char, int>::iterator it; int start, end, max_len = 0; for(start = 0, end = 0; end < s.length(); end++) { it = hash_tbl.find(s[end]); if(it != hash_tbl.end() && it->second >= start) { start = it->second + 1; } hash_tbl[s[end]] = end; max_len = max(max_len, end - start + 1); } return max_len; } };