zoukankan      html  css  js  c++  java
  • [LeetCode] 76. 最小覆盖子串

    题目链接 : https://leetcode-cn.com/problems/minimum-window-substring/

    题目描述:

    给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。

    示例:

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

    思路:

    滑动窗口

    我们只要保证窗口(队列)字符串含有t中字符的个数大于等于t里相应元素个数.如方法一

    还有一种方法记录队列元素和t中元素的差异,直接看代码,很好理解!

    代码:

    lass Solution:
        def minWindow(self, s: 'str', t: 'str') -> 'str':
            from collections import Counter
            t = Counter(t)
            lookup = Counter()
            start = 0
            end = 0
            min_len = float("inf")
            res = ""
            while end < len(s):
                lookup[s[end]] += 1
                end += 1
                #print(start, end)
                while all(map(lambda x: lookup[x] >= t[x], t.keys())):
                    if end - start < min_len:
                        res = s[start:end]
                        min_len = end - start
                    lookup[s[start]] -= 1
                    start += 1
            return res
    

    另一种方法

    python

    class Solution:
        def minWindow(self, s: 'str', t: 'str') -> 'str':
            from collections import defaultdict
            lookup = defaultdict(int)
            for c in t:
                lookup[c] += 1
            start = 0
            end = 0
            min_len = float("inf")
            counter = len(t)
            res = ""
            while end < len(s):
                if lookup[s[end]] > 0:
                    counter -= 1
                lookup[s[end]] -= 1
                end += 1
                while counter == 0:
                    if min_len > end - start:
                        min_len = end - start
                        res = s[start:end]
                    if lookup[s[start]] == 0:
                        counter += 1
                    lookup[s[start]] += 1
                    start += 1
            return res
    

    java

    class Solution {
        public String minWindow(String s, String t) {
            Map<Character, Integer> lookup = new HashMap<>();
            for (char c : s.toCharArray()) lookup.put(c, 0);
            for (char c : t.toCharArray()) {
                if (lookup.containsKey(c)) lookup.put(c, lookup.get(c) + 1);
                else return "";
            }
            int start = 0;
            int end = 0;
            int min_len = Integer.MAX_VALUE;
            int counter = t.length();
            String res = "";
            while (end < s.length()) {
                char c1 = s.charAt(end);
                if (lookup.get(c1) > 0) counter--;
                lookup.put(c1, lookup.get(c1) - 1);
                end++;
                while (counter == 0) {
                    if (min_len > end - start) {
                        min_len = end - start;
                        res = s.substring(start, end);
                    }
                    char c2 = s.charAt(start);
                    if (lookup.get(c2) == 0) counter++;
                    lookup.put(c2, lookup.get(c2) + 1);
                    start++;
                }
            }
            return res; 
        }
    }
    

    下面介绍关于滑动窗口的万能模板,可以解决相关问题,相信一定可以对滑动窗口有一定了解!

    还有类似题目有:

    3. 无重复字符的最长子串

    class Solution:
        def lengthOfLongestSubstring(self, s):
            """
            :type s: str
            :rtype: int
            """
            from collections import defaultdict
            lookup = defaultdict(int)
            start = 0
            end = 0
            max_len = 0
            counter = 0
            while end < len(s):
                if lookup[s[end]] > 0:
                    counter += 1
                lookup[s[end]] += 1
                end += 1
                while counter > 0:
                    if lookup[s[start]] > 1:
                        counter -= 1
                    lookup[s[start]] -= 1
                    start += 1
                max_len = max(max_len, end - start)
            return max_len
    

    76. 最小覆盖子串

    class Solution:
        def minWindow(self, s: 'str', t: 'str') -> 'str':
            from collections import defaultdict
            lookup = defaultdict(int)
            for c in t:
                lookup[c] += 1
            start = 0
            end = 0
            min_len = float("inf")
            counter = len(t)
            res = ""
            while end < len(s):
                if lookup[s[end]] > 0:
                    counter -= 1
                lookup[s[end]] -= 1
                end += 1
                while counter == 0:
                    if min_len > end - start:
                        min_len = end - start
                        res = s[start:end]
                    if lookup[s[start]] == 0:
                        counter += 1
                    lookup[s[start]] += 1
                    start += 1
            return res
    

    159. 至多包含两个不同字符的最长子串

    class Solution:
        def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int:
            from collections import defaultdict
            lookup = defaultdict(int)
            start = 0
            end = 0
            max_len = 0
            counter = 0
            while end < len(s):
                if lookup[s[end]] == 0:
                    counter += 1
                lookup[s[end]] += 1
                end +=1
                while counter > 2:
                    if lookup[s[start]] == 1:
                        counter -= 1
                    lookup[s[start]] -= 1
                    start += 1
                max_len = max(max_len, end - start)
            return max_len
    

    340. 至多包含 K 个不同字符的最长子串

    class Solution:
        def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
            from collections import defaultdict
            lookup = defaultdict(int)
            start = 0
            end = 0
            max_len = 0
            counter = 0
            while end < len(s):
                if lookup[s[end]] == 0:
                    counter += 1
                lookup[s[end]] += 1
                end += 1
                while counter > k:
                    if lookup[s[start]] == 1:
                        counter -= 1
                    lookup[s[start]] -= 1
                    start += 1
                max_len = max(max_len, end - start)
            return max_len
    

    滑动窗口题目:

    3. 无重复字符的最长子串

    30. 串联所有单词的子串

    76. 最小覆盖子串

    159. 至多包含两个不同字符的最长子串

    209. 长度最小的子数组

    239. 滑动窗口最大值

    567. 字符串的排列

    632. 最小区间

    727. 最小窗口子序列

  • 相关阅读:
    get、put、post、delete含义与区别
    中奖数据表设计方案
    mysql递归
    java Ajax跨域请求COOKIE无法带上的解决办法
    tomcat 下配置ajax 跨域 tomcat font face 跨域 java跨域
    JAVA入门教程
    解决Navicat 出错:1130-host . is not allowed to connect to this MySql server,MySQL
    Hbuilder开发app时生成ios要的mobileprovision和p12文件步骤.
    js 获取浏览器高度和宽度值(多浏览器)
    Windows netstat 查看端口、进程占用 查看进程路径
  • 原文地址:https://www.cnblogs.com/powercai/p/10957639.html
Copyright © 2011-2022 走看看