最小覆盖子串

给定两个字符串SS和TT,使用滑动窗口算法在O(n)时间复杂度内找到SS中最短的包含TT所有字符的子串。例如,对于S='XDOYEZODEYXNZ'和T='XYZ',最短子串为'YXNZ'。当不存在满足条件的子串时返回空字符串。

给出两个字符串 SS 和 TT,要求在O(n)O(n)的时间复杂度内在 SS 中找出最短的包含 TT 中所有字符的子串。
例如:

S ="XDOYEZODEYXNZ"S=“XDOYEZODEYXNZ”
T =“XYZ"T=“XYZ”
找出的最短子串为"YXNZ”“YXNZ”.

注意:
如果 SS 中没有包含 TT 中所有字符的子串,返回空字符串 “”;
满足条件的子串可能有很多,但是题目保证满足条件的最短的子串唯一。

import sys

class Solution(object):
    def minWindow(self, S, T):
        window = dict()  # 窗口字典,统计该窗口中字符的数量
        target = dict()  # 目标字符串字典,统计字符串T中的字符数量
        for c in T:
            target[c] = target.get(c, 0) + 1
        left = 0  # 记录窗口左下标
        right = 0  # 记录窗口右下标
        start = 0  # 记录覆盖子串开头位置
        count = 0  # 标志窗口中字符是否满足目标
        minLen = sys.maxsize  # 最小子串长度

        while right < len(S):
            tmp = S[right]
            right += 1
            if tmp in target:
                window[tmp] = window.get(tmp, 0) + 1  # 右边进窗口,字符个数加一
                if window[tmp] == target[tmp]:  # window中字符个数和target中相等时,count += 1
                    count += 1
            while count == len(target):  # count == len(target) 时,说明当前window窗口为S中包含T的子串
                if right - left < minLen:  # 窗口长度小于最小长度则更新
                    start = left
                    minLen = right - left
                ch = S[left]  # 窗口左端点字符
                left += 1  # 左端点向右滑动
                if ch in target:  # 左端点字符在T中时
                    if window[ch] == target[ch]: # window中字符个数和target中相等时,count -= 1
                        count -= 1  
                    window[ch] -= 1  # 左边出窗口,字符个数减一
        return "" if minLen == sys.maxsize else S[start:start + minLen]

s = Solution()
s.minWindow("XDOYZZDEYXNZ","XYZ")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值