ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【数组&双指针】LeetCode 76. 最小覆盖子串【困难】

2022-04-27 20:34:03  阅读:145  来源: 互联网

标签:子串 字符 right 窗口 个数 char 76 need LeetCode


给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
 

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"


示例 2:

输入:s = "a", t = "a"
输出:"a"


示例 3:

输入: s = "a", t = "aa"
输出: ""

解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
 

提示:

1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
 

进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

【分析】

双指针方案。

首先:

(1)用valid表示目标字符窗中每一类字符的个数是否都满足条件;

(2)用hash表need记录目标串中每一个字符的个数;

(3)用hash表window记录当前窗口中,包含的目标字符的个数;

(4)用length记录当前window窗口的长度。

思路:

遍历源字符串,利用双指针,记录窗口的位置,当窗口中每个目标字符的个数与目标字符串中对应字符的个数都相等时,就停止移动右侧指针,开始缩小左侧指针。

缩小左侧指针时,不断更新窗口长度,并更新窗口中每个目标字符的个数,当窗口中目标字符的个数与目标字符串中的对应字符的个数相等时,就减小有效长度,缩小窗口。

注意:

这里,为了避免边界条件的讨论,我们将双指针的查找区间设置为[left, right),即左闭右开的查找区间。

那么,初始化查找区间就是[0, 0],最后一个查找区间就是[left, n)。

这种情况下初始查找区间[0, 0),窗口长度为0,只要右侧指针移动一步,窗口中就包含一个元素,同时,窗口的长度就是length = right - left,比较方便。

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need = dict()
        window = dict()
        # 用need记录所有目标字符的个数
        for _char in t:
            if _char not in need:
                need[_char] = 0
                window[_char] = 0
            need[_char] += 1

        # 用双指针遍历源字符串
        left, right = 0, 0
        # 有效长度:记录窗口中目标字符的每一类字符是否个数已经满足,满足就加1
        valid = 0
        # 记录窗口的右侧位置
        start = 0
        # 将窗口长度初始化为一个无效值,即大于源字符串的长度值
        length = len(s) + 1
        # 右指针遍历字符串的每一个位置:作为窗口右侧结束位置
        while right < len(s):
            right_char = s[right]
            right += 1  # 增大窗口
            # 窗口内的最后一个字符在目标字符串中
            if right_char in need:
                # 更新窗口中的字符个数
                window[right_char] += 1
                # 当前字符在窗口中的字符个数与目标字符串的字符个数相等,更新有效长度
                if need[right_char] == window[right_char]:
                    valid += 1

            # 当窗口中的每一类字符个数都与目标串中的每一类字符个数相等,就不断缩小左侧指针
            while valid == len(need):
                # 更新最小的窗口长度
                if right - left < length:
                    start = left
                    length = right - left

                first_char = s[left]
                left += 1  # 缩小窗口

                # 左侧字符在目标字符里面
                if first_char in need:
                    # 当前字符在窗口中的个数,与目标串个数相等,就减少有效长度
                    if window[first_char] == need[first_char]:
                        valid -= 1
                    # 更新窗口中的字符个数
                    window[first_char] -= 1

        return "" if length == len(s) + 1 else s[start:start + length]

 

标签:子串,字符,right,窗口,个数,char,76,need,LeetCode
来源: https://www.cnblogs.com/ariel-dreamland/p/16200412.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有