力扣 hot100 最小覆盖子串 滑动窗口 字符计数

👨‍🏫 题目地址

在这里插入图片描述

💖 Code 24.5.24

class Solution {
    public String minWindow(String s, String t) {
        //维护s串中滑动窗口中各个字符出现次数
        Map<Character, Integer> hs = new HashMap<>();
        //维护t串中各个字符出现次数
        Map<Character, Integer> ht = new HashMap<>();
        for (int i = 0; i < t.length(); i++) {
            ht.put(t.charAt(i), ht.getOrDefault(t.charAt(i), 0)+1);
        }
        String ans="";
        //cnt维护s串[left,right]中满足t串的元素的个数,记录相对应字符的总数
        int len=Integer.MAX_VALUE,cnt=0;
        //区间[left,right]表示当前滑动窗口
        for (int left=0,right = 0; right < s.length(); right++) {
            hs.put(s.charAt(right), hs.getOrDefault(s.charAt(right), 0)+1);
            //如果ht表中也包含当前字符
            if (ht.containsKey(s.charAt(right))) {
                //并且hs表中的字符个数<=ht表中的字符个数,说明该字符是必须的,并且还未到达字符串t所要求的数量
                if (hs.get(s.charAt(right))<=ht.get(s.charAt(right))) {
                    cnt++;
                }
            }
            //收缩滑动窗口
            //如果左边界的值不在ht表中 或者 它在hs表中的出现次数多于ht表中的出现次数
            while(left < right && (!ht.containsKey(s.charAt(left)) || hs.get(s.charAt(left)) > ht.get(s.charAt(left)))){
                    hs.put(s.charAt(left),hs.get(s.charAt(left)) - 1);
                    left++;
            }
            //此时滑动窗口包含符串 t 的全部字符
            if (cnt==t.length()&&right-left+1<len) {
                len=right-left+1;
                ans=s.substring(left,right+1);
            }
        }
        return ans;
    }
}

🍻 code1

class Solution {
    public String minWindow(String s, String t)
	{
		int n = s.length();
		int m = t.length();
		if (n < m)
			return "";

		char[] tt = t.toCharArray();
		int[] cnt = new int[128];// 字符计数数组
		for (int i = 0; i < m; i++)
			cnt[tt[i]]++;// 统计t串的字符

		int l = 0, r = 0;
		int left = 0, right = 0, ans = Integer.MAX_VALUE;
		while (r < n)
		{
			System.out.println(m);
			char c = s.charAt(r++);
			if (cnt[c] > 0)// 在 t串 中出现过的字符才减,减到 0 即止
				m--;
			cnt[c]--;// 当前子串 抵消 t串 的字符统计
			while (m == 0)// 当前子串完全覆盖完 t 串
			{
				if (r - l < ans)// 更新答案
				{
					ans = r - l;
					left = l;
					right = r;
				}
				c = s.charAt(l++);// 子串左边界右移
				// cnt[c] == 0 : 字符c是 t 串的。如果不是t串的,cnt[c] 为负值
				if (cnt[c] == 0)
					m++;
				cnt[c]++;// 取消对当前字符的统计
			}
		}
		if (ans == Integer.MAX_VALUE)
			return "";
		else
			return s.substring(left, right);
	}
}

👨‍🏫 参考题解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值