LeetCode第76题:最小覆盖子串(困难)

LeetCode第76题:最小覆盖子串(困难)

  • 题目:给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
    在这里插入图片描述
  • 解题思路:我认为题干说的有点不明确,刚开始我以为只要包含就可以,几个不重要。但试过之后发现不行。增加了一个数组,来表示匹配过的字符。但还是没过,最后那个测试那么长的串我也是醉了。。。
class Solution {
    public String minWindow(String s, String t) {
        int len1 = s.length();
        int len2 = t.length();
        if (len1 == 0 || len2 == 0)  return "";
        //i代表最小子串的长度
        for(int i=len2;i<=len1;i++){
            //j代表最小字串的起始位置
            for(int j=0;j<=len1-i;j++){
                //截取最小子串
                String ss = s.substring(j,j+i);
                int[] c = new int[i];
                for(int k=0;k<i;k++) c[k]=0;
                //逐个检查t中的字符
                int n;
                for(n=0;n<len2;n++){
                    //从最短字符的第一个开始匹配
                    int m;
                    for(m=0;m<i;m++){
                        //当前位置与t中第n个字符相同,并且该位置没有匹配过
                        if(ss.charAt(m)==t.charAt(n) && c[m]==0){
                            //相同则标记为匹配过,再匹配下一个字符
                            c[m]=1;
                            break;
                        }
                    }
                    if(m==i) break;
                }
                if(n==len2) return ss;
            }
        }
        return "";
    }
}

在这里插入图片描述

  • 题解做法:官方解法采用了双指针滑动窗口的方法,具体思路如下。
class Solution {
    public String minWindow(String s, String t) {

        if (s.length() == 0 || t.length() == 0) {
            return "";
        }

        // 记录t中不同字符出现的次数
        Map<Character, Integer> dictT = new HashMap<Character, Integer>();
        for (int i = 0; i < t.length(); i++) {
            int count = dictT.getOrDefault(t.charAt(i), 0);
            dictT.put(t.charAt(i), count + 1);
        }

        // t中不同字符数量
        int required = dictT.size();

        // 窗口的左右
        int l = 0, r = 0;

        //记录窗口中的不同字符数量
        int formed = 0;

        // 记录窗口中不同字符出现的位置
        Map<Character, Integer> windowCounts = new HashMap<Character, Integer>();

        // 表示窗口大小,左边位置右边位置
        int[] ans = {-1, 0, 0};

        while (r < s.length()) {
            // 向窗口中加入字符
            char c = s.charAt(r);
            int count = windowCounts.getOrDefault(c, 0);
            windowCounts.put(c, count + 1);

            //判断窗口中字符出现的次数与t中是否相同,相同则符合要求的字符数量加1
            if (dictT.containsKey(c) && windowCounts.get(c).intValue() == dictT.get(c).intValue()) {
                formed++;
            }

            // 窗口符合要求
            while (l <= r && formed == required) {
                c = s.charAt(l);
                // 保存最小窗口
                if (ans[0] == -1 || r - l + 1 < ans[0]) {
                    ans[0] = r - l + 1;
                    ans[1] = l;
                    ans[2] = r;
                }

                // 将最左端的字符个数减去
                windowCounts.put(c, windowCounts.get(c) - 1);
                if (dictT.containsKey(c) && windowCounts.get(c).intValue() < dictT.get(c).intValue()) {
                    formed--;
                }

                // 移动窗口左侧,缩小窗口
                l++;
            }

            // 移动窗口位置,扩大窗口
            r++;   
        }

        return ans[0] == -1 ? "" : s.substring(ans[1], ans[2] + 1);
    }
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/minimum-window-substring/solution/zui-xiao-fu-gai-zi-chuan-by-leetcode-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述

发布了100 篇原创文章 · 获赞 12 · 访问量 2368

猜你喜欢

转载自blog.csdn.net/new_whiter/article/details/104557443