76. 最小覆盖子串(困难)

这绝对是我目前为止debug最长时间的算法代码,三、四个小时,你能信。
还算是做出来了,中午都没睡觉。太菜了,总结经验,再次出发。

最小覆盖字串

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

示例:

  • 输入: S = “ADOBECODEBANC”, T = “ABC”
  • 输出: “BANC”
    说明:

如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

在这里插入图片描述

class Solution {
   public static String minWindow(String s, String t) {
        if (s.length() < t.length() || s.length() == 0 || t.length() == 0) {
            return "";
        }

        if (s.length() == t.length()) {
            if (s.equals(t)) {
                return t;
            }
        }
        HashMap<Character, Integer> hash = new HashMap<Character, Integer>();
        HashMap<Character, Integer> record = new HashMap<Character, Integer>();
        int begin = 0;
        int end = -1;
        int left = -1;
        int right = -1;
        int count = 0;
        int sLength = s.length();
        final int tLength = t.length();
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < tLength; i++) {             //记录t字符串中的每个字母共有多少个
            char ch = t.charAt(i);
            hash.put(ch, hash.getOrDefault(ch, 0) + 1);
        }
        //System.out.println(hash);
        for (int i = 0; i < sLength; i++) {
            char ch = s.charAt(i);
            // System.out.println("count ="+ count+"  "+ch+" begin ="+begin+"  i = "+i);
            //System.out.println("hash = "+hash +"record "+record);
            if (hash.get(ch) != null) {
                record.put(ch, record.getOrDefault(ch, 0) + 1);
                if (record.get(ch) <= hash.get(ch)) {
                    count++;
                    if (count == 1) {
                        begin = i;
                    }
                    if (count == tLength) {                   //当滑动窗口满了时

                        // System.out.println("我到这了");
                        if (i - begin + 1 < min) {
                            left = begin;
                            right = i;
                        }
                        min = Math.min(min, i - begin + 1);
                        //System.out.println(begin);
                        ch = s.charAt(begin);
                        //System.out.println(ch);
                        record.put(s.charAt(begin), record.get(s.charAt(begin)) - 1);
                        //System.out.println("---------"+record);
                        int start = begin;
                        while (start < i) {
                            start++;
                            if (start >= sLength)
                                break;
                            char c = s.charAt(start);
                            //System.out.println("start = "+c+"  "+start+"   "+i);
                            if (record.get(c) != null) {
                                if (record.get(c) <= hash.get(c)) {
                                    begin = start;
                                    //System.out.println("count ="+count);
                                    count--;
                                    //System.out.println("count ="+count);
                                    break;
                                } else {
                                    record.put(c, record.get(c) - 1);
                                }
                            }
                        }

                    }

                } else {
                    if (begin >= 0 && s.charAt(begin) == ch) {		//如果超出字符且
                        record.put(ch, record.get(ch) - 1);
                        int start = begin;
                        while (start < i) {
                            start++;
                            if (start >= sLength)
                                break;
                            char c = s.charAt(start);
                            //System.out.println("start = "+c+"  "+start+"   "+i);
                            if (record.get(c) != null) {
                                if (record.get(c) <= hash.get(c)) {
                                    begin = start;
                                    break;
                                } else {
                                    record.put(c, record.get(c) - 1);
                                }
                            }
                        }
                    }
                }
            }

        }

        if (min <= 0 || min == Integer.MAX_VALUE)
            return "";
        else
            return s.substring(left, right + 1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值