📅  最后修改于: 2023-12-03 14:55:20.086000             🧑  作者: Mango
在本题中,我们需要找到一个最小的K,使得给定的字符串中,每个长度至少为K的子串都包含字符c。例如,对于字符串"abcdbccc"和字符c='c',最小的K为3,因为"bcc"是长度为3的子串且含有字符c。
对于一个长度为n的字符串,我们可以暴力枚举所有长度大于等于K的子串,并判断每个子串是否包含字符c。时间复杂度为O(n^2K)。
def min_k(s, c):
n = len(s)
for k in range(1, n + 1):
for i in range(n - k + 1):
if c not in s[i:i+k]:
break
else:
return k
return -1
我们可以通过二分答案来优化时间复杂度。假设当前二分到的K为mid,我们可以使用滑动窗口来判断是否存在长度至少为mid的子串不包含字符c。具体来说,我们维护一个滑动窗口,使得窗口内的子串长度恰好为mid,然后移动窗口,判断窗口内是否包含字符c。时间复杂度为O(nlogn)。
def has_substring(s, c, k):
n = len(s)
freq = [0] * 26
for i in range(k):
freq[ord(s[i]) - ord('a')] += 1
for i in range(k, n):
if freq[ord(c) - ord('a')] > 0:
return True
freq[ord(s[i-k]) - ord('a')] -= 1
freq[ord(s[i]) - ord('a')] += 1
return freq[ord(c) - ord('a')] > 0
def min_k(s, c):
n = len(s)
l, r = 1, n
ans = -1
while l <= r:
mid = (l + r) // 2
if has_substring(s, c, mid):
ans = mid
r = mid - 1
else:
l = mid + 1
return ans
本题可以通过枚举和二分答案来求解。通过二分答案可以将时间复杂度从O(n^2K)降低到O(nlogn)。