【leetcode】76. 最小覆盖子串(Java)

题目描述

题目链接76. 最小覆盖子串
在这里插入图片描述
在这里插入图片描述

题解

滑动窗口,详细注释

class Solution {
    public String minWindow(String s, String t) {
        if (t.length() > s.length()) return "";
        //用来记录完全覆盖t,每种字母还需要多少个
        int[] map = new int[128];
        char[] cs = s.toCharArray();
        char[] ct = t.toCharArray();
        //count用来记录,当前滑动窗口中,还缺几个字母才能覆盖t
        //left为滑动窗口的左边界
        int count = 0, left = 0;
        String res = "";
        //统计一下t中每种字母要多少个,完全覆盖t一共要多少个字母
        for (int i = 0; i < ct.length; i++){
            map[ct[i]]++;
            count++;
        }
        //遍历滑动窗口的右边界
        for (int right = 0; right < cs.length; right++){
        
        	//如果t之中包含当前这个字母,则覆盖t所需的字母就要减少一个,count--
            if (map[cs[right]] > 0){
                count--;
            }
            
            //无论t之中包不包含当前字母,map都--,如果t中出现过,频率要减少,
            //如果t中没出现过的话,当前字母的频率就变为负数,
            //一定要减少,一会儿移动左边界的时候要用
            map[cs[right]]--;
            
            //count == 0,即t之中所有的字母都集齐了,接下来需要移动左边界
            if (count == 0){
            	//此时滑动窗口中多余的字母频率在map中都是负数,所以当左边界指向的字母是多余的,
            	//左边界就要右移,直到map[cs[left]] == 0,这时就不能在移动了,
            	//因为如果再移动的话,map[cs[left]]就变为1了,也就是说t中又需要一个cs[left]了
                while (map[cs[left]] < 0){
                	//移动左边界
                    map[cs[left]]++;
                    left++;
                }
                
                //第一个答案或者当前窗口比res小,更新res。
                if (res.length() == 0 || right - left + 1 < res.length()){
                    res = s.substring(left, right + 1);
                }
                
                //再移动一个左边界,这时map[cs[left]]应该变为1了,覆盖t的count也增加1
                map[cs[left]]++;
                left++;
                count++;
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值