LeetCode 76. Minimum Window Substring

简介: 给定一个字符串S和一个字符串T,找到S中的最小窗口,它将包含复杂度为O(n)的T中的所有字符。

v2-4e1a6d0cf156099afb87bd1e7f1cd3c7_1440w.jpg

Description



Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).


Example:


Input: S = "ADOBECODEBANC", T = "ABC"

Output: "BANC"


Note:

If there is no such window in S that covers all characters in T, return the empty string "".


If there is such window, you are guaranteed that there will always be only one unique minimum window in S.


描述



给定一个字符串S和一个字符串T,找到S中的最小窗口,它将包含复杂度为O(n)的T中的所有字符。

例: 输入:S ="ADOBECODEBANC",T ="ABC" 输出:"BANC"

注意:

如果S中没有覆盖T中所有字符的窗口,则返回空字符串“”。

如果有这样的窗口,则保证在S中始终只有一个唯一的最小窗口。


思路



  • 题意是给定两个字符串,分别是S,T. 找到S中这样的字符串C,使得C包含T中的所有字符,返回长度最小的字符串C.
  • 要返回最短的字符串,则C的开头和结尾一定是T中的字符,如果C开头不是T中的字符,C一定不是最短,因为去掉仍然满足条件且更短.
  • 我们遍历一边数组,记下T中的字符在s中的位置,记录在indexs中.
  • 我们用两个指针left,right. 其职位indexs中的值,指向S中在T中出现的字符索引.
  • 每次检查s\left:right]是否包含T,若是
  • 我们记录下此时的字符串res,然后left向右移动,继续检查当前字符串是否满足条件.
  • 若不是,right向右移动,直到末尾.
  • 返回res.


注意



  • 检查当前字符串C是否包含T,是要保证T中的所有字符在T中出现了足够的次数.
  • 我们用两个字典vd, nvd.
  • vd记录T中每个字符出现的次数,nvd用于记录当前字符串C中有效字符出现的字符.
  • 当nvd中的每个值都大于等于vd中的每个值时,此时C字符串才是有效的字串.
  • 我们更新res字符串时,检查当前C的长度是否小于res,若是才更新res.


class Solution:
    def minWindow(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: str
        """
        left, right = 0, 0
        # valid count 表示一共需要的有效的总数
        # now valid count 目前找到的有效的总数
        vc, nvc = 0, 0
        # res 用于存储结果,存储字符串的开始和结尾
        res = [-1, -1]
        # 用于存储t中的字母出现在s中的每一个位置
        indexs = []
        # vd :valid dict 用于记录目标字符串中每个字符需要出现的次数
        # nvd: now valid dict 目前找的的有效字符的个数
        vd, nvd = {}, {}
        # 找到t中的所有字母在t中的位置
        for i in range(len(s)):
            if s[i] in t:
                indexs.append(i)
        if not indexs:
            return ""
        # 初始化vd,nvd数组
        for item in t:
            vc += 1
            nvd[item] = 0
            vd[item] = vd[item]+1 if item in vd else 1
        # 遍历每一个节点
        for right in range(len(indexs)):
            nvd[s[indexs[right]]] += 1
            # 如果当前字母的个数没有超过最大需要的次数,则当前字母出现有效
            # nvc自增一次
            if nvd[s[indexs[right]]] <= vd[s[indexs[right]]]:
                nvc += 1
            # 如果当前字符欻满足条件,即包含t
            while self.check(left, right, vc, nvc):
                # 将t记录在结果数组中
                self.put(res, indexs, left, right)
                # 将当前字母剔除
                nvd[s[indexs[left]]] -= 1
                # 如果当前字符出现小于需要的次数,则有效字符总数减一
                if nvd[s[indexs[left]]] < vd[s[indexs[left]]]:
                    nvc -= 1
                # left指针向右移动
                left += 1
        return '' if res[0] == -1 else s[res[0]:res[1]+1]
    def check(self, left, right, vc, nvc):
        # 当left大于right返回False
        if left > right:
            return False
        # 当当前有效此处与需要的有效次数相等事后返回Ture
        elif vc == nvc:
            return True
        # 其他情况返回False
        else:
            return False
    def put(self, res, indexs, left, right):
        subtraction = res[1]-res[0]
        # 如果当前res数组为空或者当前有效的字符串小于res数组中的字符串
        # 更新res数组
        if subtraction == 0 or subtraction > indexs[right]-indexs[left]:
            res[0], res[1] = indexs[left], indexs[right]
if __name__ == "__main__":
    so = Solution()
    res = so.minWindow(s="cabwefgewcwaefgcf", t="cae")
    print(res)


源代码文件在这里.


目录
相关文章
|
Java
Leetcode 3. Longest Substring Without Repeating Characters
此题题意是找出一个不包含相同字母的最长子串,题目给出了两个例子来说明题意,但这两个例子具有误导性,让你误以为字符串中只有小写字母。还好我是心机boy,我把大写字母的情况也给考虑进去了,不过。。。。字符串里竟然有特殊字符,于是贡献了一次wrong answer,这次我把ascii字符表都考虑进去,然后就没问题了。这个故事告诫我们在编程处理问题的时候一定要注意输入数据的范围,面试中可以和面试官去确认数据范围,也能显得你比较严谨。
98 3
|
Java 程序员 开发者
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之二:编码实现
本文是《LeetCode第三题(Longest Substring Without Repeating Characters)三部曲》的第二篇,前一篇文章已经列出了完整的解题思路,今天来将此思路转化为具体的Java代码
145 0
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之二:编码实现
|
Java 程序员 开发者
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一:解题思路
本文回顾了笔者对LeetCode第三题(Longest Substring Without Repeating Characters)的解题和优化思路,希望有兴趣的读者来一起广泛讨论
174 1
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一:解题思路
|
Java 程序员 开发者
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化
本文是《LeetCode第三题(Longest Substring Without Repeating Characters)三部曲》的第二篇,前一篇文章已经列出了完整的解题思路,今天来将此思路转化为具体的Java代码
172 0
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化
|
索引
Leetcode-Medium 5. Longest Palindromic Substring
Leetcode-Medium 5. Longest Palindromic Substring
147 0
|
存储 Java 索引
LeetCode 3: 无重复字符的最长子串 Longest Substring Without Repeating Characters
题目: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 Given a string, find the length of the longest substring without repeating characters. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
1052 0

热门文章

最新文章