C++解法一:
class Solution { public: int lengthOfLongestSubstring(string s) { int m[256] = {0},left = 0, res = 0; for(int index = 0; index < s.size(); ++index) { if(m[s[index]] == 0|| m[s[index]] < left) { res = max(res,index-left+1); }else{ left = m[s[index]]; } m[s[index]] = index+1; } return res; } };
算法解读:
1) 这里使用哈希的思想,把256个可能的字符都考虑在内,字符的ASCⅡ编码作为数组下标进行映射。如m[a]等价于m[97]。
2) res其实是result的缩写,表示返回的最大无重复子串的长度,left表示当前正在判断的子串的起始位置。
3) 进行一个for循环,当满足(m[s[i]] == 0 || m[s[i]] < left)条件时候,计算子串长度,并且与res比较最长并取之。
这里的m[s[i]]表示第i个字符上一次出现的位置,如果从来没有出现过即m[s[i]]==0, 则表示无重复;如果m[s[i]] < left
则表示上次出现的位置在当前判断的字串起始位置的左边,不重复。
否则,(m[s[i]] != 0 && m[s[i]] >= left),重复。此时要更新left的值为m[s[i]],即不left更新为当前字符与上一次重复
的字符位置的下一位 。这里的i+1 是因为i是从0开始的下标,而我们需要的是从1开始的序号。
4) i偏移都每一个字符都要几下当前的位置,即m[s[i]] = i + 1 。
C++解法二
复制代码 class Solution { public: int lengthOfLongestSubstring(string s) { vector<int> m(256, -1); int res = 0, left = -1; for (int i = 0; i < s.size(); ++i) { left = max(left, m[s[i]]); m[s[i]] = i; res = max(res, i - left); } return res; } };
算法分析:
1)与算法一思想一样,只是进行了精简。
2)每次循环,将left更新 max(left, m[s[i]]),如果s[i]在left的右边且