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.
分析
假设子串里含有重复字符,则父串一定含有重复字符,单个子问题就可以决定父问题,因此可以用贪心法Greedy Algorithm。跟动规不同,动规里,单个子问题只能影响父问题,不足以决定父问题。从左往右扫描,当遇到重复字母时,以上一个重复字母的 index+1,作为新的搜索起始位置,直到最后一个字母,复杂度是 O(n)。
![](https://images2015.cnblogs.com/blog/567993/201611/567993-20161130165355927-1370198039.png)
该题的关键在于利用一个数组记录每个字母上一次的出现位置 postion
time complexity O(n)
space complexity O(1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Solution { public : int lengthOfLongestSubstring(string s) { int len = s.size(); int p[128]; fill(p, p + 128, -1); int index_start = 0, max_len = 0; for ( int i = 0; i < len; ++i){ if (p[s[i]] >= index_start ){ //说明在start后面出现了两个重复字母,需要计算子串。 【 这里不能写为 p[s[i]] != -1 】 //并不是只要出现重复的就需要计算,而是上一个重复的字符在现在index_start的 后面才需要计算,比如: // a b c d e f g d h ! # c @ * ) _ ~ // |-------------| // |-------------o---------| // | // 遇到这里的c并不需计算,因为新的start位置是e,而e之后并没有出现c max_len = max(max_len, i - index_start); index_start = p[s[i]] + 1; } p[s[i]] = i; } return max(max_len, len - index_start); } }; |