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.
给定一个字符串,求出它最长的没有重复字符的子串的长度。
法一:定义字符串str、rst,遍历给定的字符串s,每遍历一个字符c,判断它是否在字符串str中存在,若不存在,直接添加到字符串str末尾,若存在,比较字符串str与rst的长度,若前者比后者长,将字符串赋给rst,并抹去字符串str从0到字符c处的所有字符。当遍历结束时,字符串rst即为给定字符串s的最长不含重复字符的子串。当当前最长子串(即字符串rst)的长度比 剩余字符数+当前字符串长度(即字符串str) 还长时,没必要继续遍历下去,因为已经不可能存在比字符串rst还长的子串了。代码如下:
int lengthOfLongestSubstring(std::string s) { size_t pos = 0; std::string str, rst; int cur = 0, total = s.length(); for (auto c : s) { pos = str.find(c); if (pos != std::string::npos) { if (str.length() > rst.length()) rst = str; str = str.substr(pos + 1); if (rst.length() >= str.length() + total - cur) break; } str.append(1, c); cur++; } int cur_len = str.length(); int record_len = rst.length(); return cur_len > record_len ? cur_len : record_len; }
法二:法一中遍历给定字符串是无法避免的,查找字符str是否含有字符c可以用HashMap来做,因为最终只需要最长不含重复字符的子串的长度,我们甚至不需要保存临时字符串str,改进后的代码如下:
int lengthOfLongestSubstring(std::string s) { std::unordered_set<char> set; int left = 0,length = 0, cnt = 0, cur = 0, total = s.length(); for (char c : s) { if (set.find(c) != set.end()) { cnt = set.size(); if (cnt > length) length = cnt; char ch = '\0'; while (set.find(c) != set.end()) { ch = s.at(left); auto iter = set.find(ch); if (iter != set.end()) set.erase(iter); left++; } } set.insert(c); cur++; if (length >= (int)set.size() + total - cur) break; } cnt = set.size(); return length > cnt ? length : cnt; }