你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

算法模板:滑动窗口(Java版)

2022/1/2 7:28:02

代码改写自: labuladong 的算法小抄
题目来源自: leetcode 76. 最小覆盖子串

题目描述


具体代码

class Solution {
    public String minWindow(String s, String t) {
        // 滑动窗口(记录的是窗口内所有的元素以及其对应的个数)
        Map<Character, Integer> window = new HashMap<>();
        // 需求窗口(记录目标字符串对应的所有元素以及其对应的个数)
        Map<Character, Integer> need = new HashMap<>();
        // 初始化需求窗口
        for(char c : t.toCharArray()) {
            // need如果不存在该元素,则将其直接插入,且对应的个数为1;否则将其个数+1
            need.put(c, need.getOrDefault(c, 0).intValue() + 1);
        }
        // left、right分别为window的左右边界
        // 当window对应的某个元素个数达到了need的要求,valid+1
        // 如:need中要求元素'a'等于2, 则当window中的'a'也等于2时,valid+1
        // 当valid等于need的长度时,表明window已经达到了need中的所有元素的要求
        int right = 0, left = 0, valid = 0;
        // 用于记录最小子串的开始下标和长度
        int start = 0, length = Integer.MAX_VALUE;
        // 当window的右边界到达字符串边缘后退出循环
        while(right < s.length()) {
            // 取出当前元素,并将window右边界右移
            char c = s.charAt(right++);
            if(need.containsKey(c)) {
                // window对应的元素个数+1
                window.put(c, window.getOrDefault(c, 0).intValue() + 1);
                // 如果window中,该元素的个数符合了need的要求则valid+1
                if(window.get(c).intValue() == need.get(c).intValue()) {
                    ++valid;
                }
            }
            // 当valid等于need的长度时,表明window已经达到了need中的所有元素的要求,
            // 开始考虑window左侧是否需要缩减窗口
            while(valid == need.size()) {
                // 如果当前窗口的子串长度小于先前的子串,则用其替换
                if(right - left < length) {
                    start = left;
                    length = right - left;
                }
                // 取出当前的左侧元素,并将window左边界右移
                char d = s.charAt(left++);
                if(need.containsKey(d)) {
                    // 如果当前的左侧元素个数在window和need中对应的个数相同,
                    // 由于window需要缩减,所以window对应的元素的个数定然已经
                    // 不符合need所要求的个数了,因此valid也需要跟着-1
                    if(window.get(d).intValue() == need.get(d).intValue()) {
                        --valid;
                    }
                    window.put(d, window.get(d).intValue() - 1);
                }
            }
        }
        return length == Integer.MAX_VALUE ? "" : s.substring(start, start + length);
    }
}