这道题目考察的是分而治之:找到所有在字符串中出现次数少于k次的字符,然后以这些字符作为split points,这样就把原始的字符串split成多个子串(分而)。再对这些子串分别治之。
不过需要想明白的一点是,为什么可以把这些字符作为split points,根本原因在于这些字符不可能出现在我们最后想要的子串中。
此外需要注意的一点是分而治之会形成递归树。如果是上面把字符串split成尽可能多的子串,则每一层的节点会比较多,这样递归树的深度会比较小。但是如果像下面这样玩二分 分而治之,则代码最后会因为递归树的深度太深而TLE。所以在分而治之的时候,分要尽可能多。
class Solution(object):
def longestSubstring(self, s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
if s == "":
return 0
char_counter = {}
for c in s:
if c not in char_counter:
char_counter[c] = 1
else:
char_counter[c] += 1
satisfy = True;
for c in char_counter:
if char_counter[c] < k:
satisfy = False
break
if satisfy:
return len(s)
str_len = len(s)
result = 0
for i in range(str_len):
if char_counter[s[i]] < k: #此处是二分,会导致递归树特别深,而TLE
result = max(self.longestSubstring(s[:i], k), result)
result = max(self.longestSubstring(s[i+1:], k), result)
break
return result