解法:
1. Brute Force方法。构建字符串S的所有可能子串,为每个子串,构建一个set,set的大小可以表征子串中字符的类别数。假设字符串长度为n,则子串个数为,时间复杂度为
,空间复杂度为
。
2. 使用三个指针。一个指针k指向遍历字符串的主循环中的字符位置,一个指针j指向子串的上一个不同种类字符位置,一个指针i指向当前合法子串的起始位置。当k位置字符与k-1位置字符相同时continue,当k位置与k-1位置不同时,让j存储k-1位置的字符。如此一来,若子串合法,那么k位置的字符要么与k-1位置相同,要么与j位置相同。当两者均不满足时,认为出现了第三种字符,则比较k-i长度与当前最长子串长度后,令新的起始位置i为j位置向后一位,保证子串中仅有两种字符。
Python源码:
Runtime: 40 ms, faster than 71.64% of Python online submissions forLongest Substring with At Most Two Distinct Characters.
Memory Usage: 13.1 MB, less than 18.18% of Python online submissions for Longest Substring with At Most Two Distinct Characters.
class Solution(object):
def lengthOfLongestSubstringTwoDistinct(self, s):
"""
:type s: str
:rtype: int
"""
i = 0
j = -1
t = 0
for k in range(1, len(s)):
if s[k] == s[k-1]:
continue
if j >= 0 and s[j] != s[k]:
t = max(k - i, t)
i = j + 1
j = k - 1
return max(len(s) - i, t)
我的心路:
第一次在35分钟内写出一个hard问题,虽然问题本身并不难。设置了两个指针分别指向子串的首尾,一个字典保存子串中出现的两个字符和在遍历过的字符串中最后出现的位置。主循环是尾指针对原字符串的遍历。
建立字典的方法可以轻易拓展到k种类字符的子串问题的求解上——把2改为k即可。
Runtime: 40 ms, faster than 71.64% of Python online submissions forLongest Substring with At Most Two Distinct Characters.
Memory Usage: 13.4 MB, less than 9.09% of Python online submissions forLongest Substring with At Most Two Distinct Characters.
class Solution(object):
def lengthOfLongestSubstringTwoDistinct(self, s):
"""
:type s: str
:rtype: int
"""
i = 0
t = 0
char_map = {}
for j in range(len(s)):
char_map[s[j]] = j
if len(char_map) > 2:
key = min(char_map, key=char_map.get)
i = char_map.pop(key) + 1
elif j - i + 1> t:
t = j - i + 1
return t