LeetCode热题100——最小覆盖子串(12)

题目链接:https://leetcode.cn/problems/minimum-window-substring/description/?envType=study-plan-v2&envId=top-100-liked

滑动窗口

如果窗口没有包含t,那么右边界右移,如果已经包含了,那么左边界右移,找更小范围

class Solution {
    //定义两个哈希表,存储当前窗口和t字符串的字符出现次数
    Map<Character, Integer> ss = new HashMap<Character, Integer>();
    Map<Character, Integer> tt = new HashMap<Character, Integer>();

    public String minWindow(String s, String t) {
        int n = s.length();
        int m = t.length();
        //如果s长度小于t,那么不可能覆盖完
        if(n < m){
            return "";
        }
        //存储t字符串每个字符出现的次数
        for(int i = 0; i < m; i++){
            //第i个字符
            char c = t.charAt(i);
            //存储第一个字符和出现次数
            tt.put(c, tt.getOrDefault(c, 0) + 1);
        }
        //左右边界
        int l = 0, r = -1;
        //存储答案下标,ansR在右边界下一个位置
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        //遍历字符串s
        while(r < n){
            //右边界右移
            r++;
            //如果哈希表tt包含第r个字符
            if(r < n && tt.containsKey(s.charAt(r))){
                //存储r字符和出现次数
                ss.put(s.charAt(r), ss.getOrDefault(s.charAt(r), 0) + 1);
            }
            //检查窗口是否包含t
            while(check() && l <= r){
                //如果范围更小了,就更新左右边界
                if(r - l + 1 < len){
                    len = r - l + 1;
                    ansL = l;
                    ansR = l + len;
                }
                if(tt.containsKey(s.charAt(l))){
                	//收缩窗口
                    ss.put(s.charAt(l), ss.getOrDefault(s.charAt(l), 0) - 1);
                }
                //左边界右移
                l++;
            }
        }
        return ansL == -1 ? "" : s.substring(ansL, ansR);
    }

    public boolean check(){
        //创建一个迭代器,遍历tt的所有键值对
        Iterator it = tt.entrySet().iterator();
        while(it.hasNext()){
            //获取下一个键值对
            Map.Entry entry = (Map.Entry) it.next();
            //键
            Character key = (Character) entry.getKey();
            //值
            Integer val = (Integer) entry.getValue();
            //如字符的数量少了,就返回错误
            if(ss.getOrDefault(key, 0) < val){
                return false;
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值