最小覆盖子串
问题描述
输出最小覆盖子串:给定一个字符串 abglccoba
和一个目标字符串abcc
,在给定字符串找到可以覆盖目标字符串所有字符(字符个数也要对应)的最小子串,则预期结果为ccoba
思路
采用滑动窗口的思想
- 双指针,初始时,i=j=0,都在字符串的最左边,j向右移动,如果i与j之间的字符满足要求(字符个数可能会大于所需的个数),i向右移动,缩短子串
- 如果正好满足要求,记录子串长度,动态记录最小子串起始索引
代码实现
from collections import Counter
s = 'ADOBECODEBANC'
flag = 'ABC'
if len(s) < len(flag):
print('')
else:
cnt = Counter(flag)
need = len(flag) # 目标字符串的个数
minlen = len(s) + 1
i = 0
start, end = 0, -1
for j in range(len(s)):
if s[j] in cnt:
if cnt[s[j]] > 0:
need -= 1
cnt[s[j]] -= 1
while need == 0:
if minlen > j - i + 1:
minlen = j - i + 1
start, end = i, j
ch_i = s[i]
if ch_i in cnt:
if cnt[ch_i] >= 0:
need += 1
cnt[ch_i] += 1
i += 1
print(s[start:end+1])
最长公共子串
问题描述
返回两个字符串中最长的公共子串
思路
滑动窗口解决
- 遍历
短的字符串
- 问题在于
i
的变化,i是左指针
,
- 当前字符若不在长的字符串中,i更新到 j+1
- 若当前字符在长的字符串中,且
i:j+1
的子串不在长字符串中,则i向右移动
,i+1
,直到i:j+1的子串在长字符串中,也就表示直到i:j+1是一个公共子串- 若当前字符在长的字符串中,且i:j+1的子串也在长字符串中,则该子串为一个公共子串,是不是最长需要对比
代码实现
string_1 = input().strip()
string_2 = input().strip()
if len(string_1) >= len(string_2):
longstring = string_1
shortstring = string_2
else:
longstring = string_2
shortstring = string_1
start, end = 0, -1
maxlen = 0
i = 0
for j in range(len(shortstring)):
if shortstring[j] not in longstring:
i = j + 1
continue
while shortstring[i:j + 1] not in longstring:
i += 1
if shortstring[i:j + 1] in longstring:
if maxlen < j + 1 - i:
maxlen = j + 1 - i
start, end = i, j
print(shortstring[start:end + 1])
"""
输入:
abchbcedwxyzh
abcediwxyzh
"""
>