76.最小覆盖子串(带详细注释的Java版本)

public String minWindow(String s, String t) {

        if (s == null || s.length() == 0 || t == null || t.length() == 0){

            return "";

        }

        int[] need = new int[128];

        //记录需要的字符的个数

        for (int i = 0; i < t.length(); i++) {

            need[t.charAt(i)]++;  //128个字符,需要字符就在该位置+1

        }

        //l是当前左边界,r是当前右边界,size记录窗口大小(刚刚开始size无限大),count是需求的字符总个数,start是最小覆盖串开始的index

        int l = 0, r = 0, size = Integer.MAX_VALUE, count = t.length(), start = 0;

        //遍历所有字符

        while (r < s.length()) {

            char c = s.charAt(r);

            if (need[c] > 0) {//需要字符c

                count--; //需求的字符总个数-1

            }

            need[c]--;//把该字符加入窗口,如果该字符不是需要字符也加入窗口,把该字符的值-1,代表该字符多余

                      //如果该字符是需要字符也加入窗口,把该字符的值-1,代表该字符多余



            if (count == 0) { //窗口中已经包含所有需要的字符

                while (l < r && need[s.charAt(l)] < 0) { //左边有多余的字符

                    need[s.charAt(l)]++;//将该多余字符对应的值+1

                    l++;//左指针右移

                }

                if (r - l + 1 < size) {//不能右移时候挑战最小窗口大小,更新最小窗口开始的start

                    size = r - l + 1;

                    start = l;//记录下最小值时候的开始位置,最后返回覆盖串时候会用到

                }

               

                 //此时l指向第一个最小窗口的最左边(没有多余元素),也就是需要的字符串中的第一个碰到的字符

                 //l向右移动后窗口肯定不能满足了 重新开始循环

                 //在l右移之前先把第一个需要的元素值+1,代表该元素后面需要一个

                need[s.charAt(l)]++;

                //l右移一个,重新开始循环

                l++;

                //需求的字符总个数+1

                count++;

            }

            r++;

        }

        //size是否改变过,若size没有改变过则找不到满足题目要求的窗口

        return size == Integer.MAX_VALUE ? "" : s.substring(start, start + size);

    }

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值