76.最小覆盖子串【滑动窗口】

题目

76. 最小覆盖子串
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"

思路

这是一道滑动窗口的题目,首先写滑动窗口的模板。
然后回答4个问题即可。

  • 扩大窗口需要做什么操作?
  • 什么条件下缩小窗口?
  • 缩小窗口之后做什么操作?
  • 结果在扩大窗口还是缩小窗口处更新?
    然后依次填入即可。
  • 扩大窗口需要做什么操作?-----更新windows增加值,判断是windows中和need的的新增值是否相等,相等则计数+1
  • 什么条件下缩小窗口?-----缩小窗口条件为 窗口中必要的数量和need相等了。
  • 缩小窗口之后做什么操作?-----更新windows减少值,判断是windows中和need的的新增值是否相等,相等则计数-1
  • 结果在扩大窗口还是缩小窗口处更新?------因为要找最小的,所以在缩小窗口之前更新
class Solution {
    public String minWindow(String s, String t) {
        HashMap<Character,Integer> windows = new HashMap<>();
        HashMap<Character,Integer> needs = new HashMap<>();
        int left = 0, right = 0;
        int vaild = 0;
        int start = 0;
        int len = Integer.MAX_VALUE;
        for (int i = 0; i < t.length(); i++) {
            needs.put(t.charAt(i), needs.getOrDefault(t.charAt(i),0)+1);
        }

        while (right<s.length()){
            char c = s.charAt(right);
            right++;
            windows.put(c, windows.getOrDefault(c,0)+1);
            if(windows.get(c).equals(needs.get(c))){
                vaild++;
            }
            while (vaild==needs.size()){
                if(len>right-left){
                    len = right-left;
                    start = left;
                }
                char d = s.charAt(left);
                left++;
                if(windows.get(d).equals(needs.get(d))){
                    vaild--;
                }
                windows.put(d,windows.getOrDefault(d,0)-1);
            }
        }
        return len==Integer.MAX_VALUE ? "" : s.substring(start, start+len);

    }
}

posted @ 2021-04-15 20:36  火颜  阅读(60)  评论(0)    收藏  举报