Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, 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.
求最大无重复字母子字符串长度
错误解法:
思路:字符串按位计数,当有重复字符串时,记count值,并将之设为新的起点。遍历整个字符串。
- 错误1:不知有字符串操作
s[i]
- 错误2:
"dvdf"
作为输入时,思路错误出现,无法避免。 - 错误3:在繁复的逻辑细节上抠的时间太多,没有及时找到核心错误。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
char *cstr = new char[s.length() + 1];
strcpy(cstr, s.c_str());
char *p = cstr;
int max = 0;
int count = 0;
unordered_map<char,int> substr;
for (int i = 0; i < s.length(); ++i)
{
if (substr.find(*p) != substr.end()) //finded
{
max = max > count ? max : count;
count = 1;
substr.clear();
}
else
{
count++;
max = max > count ? max : count;
}
substr[*p] = i;
p = (char *)(p + 1);
}
delete [] cstr;
return max;
}
};
正确解法1:
DP方法,复杂度O(n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size()<2) return s.size();
int d=1, maxLen=1;
unordered_map<char,int> map;
map[s[0]]=0;
for(int i=1;i<s.size();i++)
{
if(map.count(s[i])==0 || map[s[i]]<i-d)
d++;
else
d= i- map[s[i]];
map[s[i]]=i;
if(d>maxLen)
maxLen = d;
}
return maxLen;
}
};
正确解法2:
/**
* Solution (DP, O(n)):
*
* Assume L[i] = s[m...i], denotes the longest substring without repeating
* characters that ends up at s[i], and we keep a hashmap for every
* characters between m ... i, while storing <character, index> in the
* hashmap.
* We know that each character will appear only once.
* Then to find s[i+1]:
* 1) if s[i+1] does not appear in hashmap
* we can just add s[i+1] to hash map. and L[i+1] = s[m...i+1]
* 2) if s[i+1] exists in hashmap, and the hashmap value (the index) is k
* let m = max(m, k), then L[i+1] = s[m...i+1], we also need to update
* entry in hashmap to mark the latest occurency of s[i+1].
*
* Since we scan the string for only once, and the 'm' will also move from
* beginning to end for at most once. Overall complexity is O(n).
*
* If characters are all in ASCII, we could use array to mimic hashmap.
*/
int lengthOfLongestSubstring(string s) {
// for ASCII char sequence, use this as a hashmap
vector<int> charIndex(256, -1);
int longest = 0, m = 0;
for (int i = 0; i < s.length(); i++) {
m = max(charIndex[s[i]] + 1, m); // automatically takes care of -1 case
charIndex[s[i]] = i;
longest = max(longest, i - m + 1);
}
return longest;
}