1 题目
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.
2 分析
双指针的方法,指向子字符串的头尾。
并且记录每个字符出现的最大位置。如果最大位置超过了左指针,那么应该更新max_counts,和左指针。
class Solution { public: int lengthOfLongestSubstring(string s) { // 用来记录char 出现的最大位置 map<char, int> memo; int max_counts = 0; // 双指针 int l = 0; int i = 0; for (; i < s.size(); ++i) { // 如果 s[i] 出现过,并且出现的位置大于等于 l ,那么表示子字符串中包含重复字符了 // 此时计算一次 max_counts. // 并且将 l 指针右移到 重复字符的下一个字符上 if (memo.find(s[i]) != memo.end() && memo[s[i]] >= l) { max_counts = max(i - l, max_counts); l = memo[s[i]] + 1; } else { } // 记录该字符出现的位置 memo[s[i]] = i; } // 因为max_counts,只有在出现重复字符的时候,更改,因此这里需要再更新一次 max_counts = max(i - l, max_counts); return max_counts; } };
不用map,使用数组记录。
class Solution { public: int lengthOfLongestSubstring(string const &s) { short ans = 0; short b = 0; // 使用数组记录 short l[256]; memset(l, 0xFF, sizeof(l)); for (short e = 0; e < s.size();) { char c = s[e]; short p = l[c]; // 当字符出现的位置,大于左指针b,小于右指针e。那么 左指针等于字符出现位置+1,否则仍等于左指针 b = (p >= b && p < e) ? p + 1 : b; // 字符出现位置应该是不会大于e的。 l[c] = e > l[c] ? e : l[c]; ++e; // 更新最终结果 ans = (e - b > ans) ? e - b : ans; } return int(ans); } };
仍然是在遍历每个元素,如果该元素出现的位置大于左指针,那么就更新max_counts.
3 总结
解题方法:双指针。
get