• Leecode no.76 最小覆盖子串


    package leecode;

    import java.util.HashMap;
    import java.util.Map;

    /**
    * 76. 最小覆盖子串
    *
    * 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
    *
    * @author Tang
    * @date 2021/12/1
    */
    public class MinWindow {

    /**
    * 滑动窗口
    * 通过left,right两个指针,不断控制窗口大小,使窗口覆盖的元素达到元素数量要求,则更新start和length
    *
    * @param s
    * @param t
    * @return
    */
    public String minWindow(String s, String t) {
    char[] all = s.toCharArray();
    char[] chars = t.toCharArray();

    //初始化window散列表
    //表示当前窗口中存在的字符的个数
    Map<Character, Integer> window = new HashMap<>();

    //初始化need散列表
    //表示每个need字符需要的个数
    Map<Character, Integer> needMap = new HashMap<>();
    for (char c : chars) {
    needMap.put(c, needMap.getOrDefault(c, 0) +1);
    }


    //窗口中已经满足need的元素个数
    //window(c) >= need(c) 的个数
    int valid = 0;

    //滑动窗口左指针
    int left = 0;
    //滑动窗口右指针
    int right = 0;

    //最小覆盖子串的起始位置
    int start = 0;
    //覆盖字符串子串最小长度
    //最后结果通过sub(start,length)截取获得
    int length = Integer.MAX_VALUE;

    //!!!反反复复执行 窗口右边界右移+窗口左边界左移操作,找到最小值则更新start和length
    //直到窗口右边界走到头
    //左毕右开原则,窗口包含left元素,不包含right元素
    while(right < all.length) {
    char c = all[right];
    //窗口右边界右移
    right++;

    //进行窗口内数据的一系列更新
    //todo
    //如果当前字符是需要的
    if(needMap.containsKey(c)) {
    //放入窗口计数中
    window.put(c, window.getOrDefault(c, 0) +1);

    //满足need的元素个数+1
    if(window.get(c).equals(needMap.get(c))) {
    valid++;
    }
    }

    System.out.println(String.format("此时窗口left:%s, right:%s",left, right));

    //判断左侧窗口是否要收缩 (已经满足子串覆盖了才考虑收缩来缩小子串)
    //执行收缩左窗口的逻辑
    while(valid == needMap.size()) {
    //执行最小覆盖子串更新
    if(right - left < length) {
    start = left;
    length = right - left;
    }

    char d = all[left];
    //窗口左边界左移
    left++;

    //进行窗口内数据的一些列更新
    //todo
    if(needMap.containsKey(d)) {
    //如果d元素是需要的,先判断是否是正好元素个数,执行valid--操作
    if(window.get(d).equals(needMap.get(d))) {
    valid--;
    }
    window.put(d, window.get(d) - 1);
    }
    }

    }

    return length == Integer.MAX_VALUE ? "" : s.substring(start, start+length);
    }


    public static void main(String[] args) {


    }


    }
  • 相关阅读:
    overflow :hidden隐藏溢出用处大
    datalist 数据展示顺序
    SEO 特定搜索和外链技巧
    Android网络地址簿同步的方式
    表单全选及取消全选
    for循环的嵌套之小星星。
    数组的方法中那些会改变原数组呢?
    for循环的嵌套之打印倒三角的星星
    Js中的排他思想
    计算阶乘的思路。
  • 原文地址:https://www.cnblogs.com/ttaall/p/15635471.html
Copyright © 2020-2023  润新知