386. 最多有k个不同字符的最长子字符串
386. 最多有k个不同字符的最长子字符串
中文English
给定字符串S,找到最多有k个不同字符的最长子串T。
样例
样例 1:
输入: S = "eceba" 并且 k = 3
输出: 4
解释: T = "eceb"
样例 2:
输入: S = "WORLD" 并且 k = 4
输出: 4
解释: T = "WORL" 或 "ORLD"
挑战
O(n) 时间复杂度
输入测试数据 (每行一个参数)如何理解测试数据?
第一种写法:(同向型双向指针)
class Solution: """ @param s: A string @param k: An integer @return: An integer """ def lengthOfLongestSubstringKDistinct(self, s, k): # write your code here if len(s) <= k: return len(s) array = [] l, max_value = len(s), 0 count = 0 j = 0 #主指针,缩小区间,维持区间内都符合条件 for i in range(l): j = i #一定要在count <= k里面,直到等于k的时候才可以,不然会出现刚好到k的情况,立马跳出循环。这样的话就不是取到最大长度了,例如j,j,j #刚好出现第一个j新字符,就跳出循环,后面就不在append到array里面了 while count <= k and j < l:#count = k 重要,否则无法更新到最长相同字符串那里 if s[j] not in array: count += 1 array.append(s[j]) j += 1 if (count <= k): max_value = max(j - i, max_value) #缩小区间 count = 0 array = [] return max_value
注:lintcode未通过,时间复杂度问题,待优化
优化版本一:通过字典的方式(外面缩减区间,里面增大区间)
class Solution: """ @param s: A string @param k: An integer @return: An integer """ def lengthOfLongestSubstringKDistinct(self, s, k): # write your code here if len(s) <= k: return len(s) counter = {} l, max_value = len(s), 0 j = 0 #主指针,缩小区间,维持区间内都符合条件 for i in range(l): #一定要在count <= k里面,直到等于k的时候才可以,不然会出现刚好到k的情况,立马跳出循环。这样的话就不是取到最大长度了,例如j,j,j #刚好出现第一个j新字符,就跳出循环,后面就不在append到array里面了 while len(counter) <= k and j < l: counter[s[j]] = counter.get(s[j], 0) + 1 j += 1 if (len(counter) <= k): max_value = max(j - i, max_value) #缩小区间 counter[s[i]] -= 1 if counter[s[i]] == 0: del counter[s[i]] return max_value
优化版本二(外面增大区间,里面缩减区间,一直缩减到符合最长不同字符为k截止,跳出循环)
class Solution: """ 同向型双指针 """ def lengthOfLongestSubstringKDistinct(self, s, k): #维持区间在满足最长不同字符k长度左右 if not s: return 0 counter = {} l = len(s) max_res = 0 j = 0 #增大区间,主指针 for i in range(l): counter[s[i]] = counter.get(s[i], 0) + 1 #缩小区间,维持最长不同字符为k,如果大于k,则开始缩减,注意大于即可,一直到等于便可以跳出循环 while len(counter) > k and j < l: counter[s[j]] -= 1 if counter[s[j]] == 0: del counter[s[j]] #可能存在多个相同的,也会一直缩减到不同字符长度k截止 j += 1 #在这里已经是符合条件的k长度了,所以可以取最大值 max_res = max(max_res, i - j + 1) return max_res