首页 > 编程语言 >算法练习题10:leetcode76最小覆盖子串-滑动窗口

算法练习题10:leetcode76最小覆盖子串-滑动窗口

时间:2024-09-03 22:51:58浏览次数:6  
标签:练习题 10 默认值 leetcode76 返回 子串 getOrDefault null 窗口

目录


题目

题目描述

约束条件

解决思路

代码

getOrDefault(c, 0) 方法

方法签名

参数

返回值

示例

getOrDefault 与 get 的主要区别

Integer 


题目

题目描述

给定两个字符串 st,请你在字符串 s 中找到包含 t 中所有字符的最小子串。

要求:

        如果 s 中存在这样一个子串,返回这个最小子串。

        如果不存在这样的子串,则返回空字符串 ""

注意:

        如果 s 中存在多个符合条件的子串,返回长度最小的那个。

  t 中的字符可以在子串中以任何顺序出现,但每个字符的出现次数必须与 t 中相同或更多。

输入: s = "ADOBECODEBANC", t = "ABC"
输出: "BANC"
解释: "BANC" 是包含 "ABC" 的最小子串。
输入: s = "a", t = "a"
输出: "a"
解释: 子串 "a" 自身就是满足条件的最小窗口。
输入: s = "a", t = "aa"
输出: ""
解释: 因为 "a" 中只包含一个 "a",不满足 "t" 中两个 "a" 的条件,因此返回空字符串。

约束条件

  s 和 t 的长度均不会超过 10^5。

       字符串 s 和 t 由英文字母组成。

解决思路

这道题可以使用滑动窗口的技巧来解决:

  1. 初始化:使用两个字典,一个存储目标字符串 t 中各字符的计数,一个存储当前窗口中各字符的计数。
  2. 扩展窗口:使用右指针逐步扩展窗口,直到窗口包含了 t 中所有字符。
  3. 缩小窗口:一旦窗口满足条件,使用左指针尝试缩小窗口以找到更小的符合条件的子串。
  4. 更新最优解:在每次找到符合条件的窗口时,更新当前最小的覆盖子串的长度及其位置。
  5. 返回结果:如果找到满足条件的子串,返回最小的那个;如果没有找到,返回空字符串。

代码

class Solution {
    // 用于存储字符串 t 中每个字符及其出现的次数
    Map<Character, Integer> ori = new HashMap<Character, Integer>();
    // 用于存储当前窗口中对应字符的出现次数
    Map<Character, Integer> cnt = new HashMap<Character, Integer>();

    public String minWindow(String s, String t) {
        int tLen = t.length();
        // 初始化 ori 字典,存储 t 中每个字符出现的次数
        for (int i = 0; i < tLen; i++) {
            char c = t.charAt(i);
            ori.put(c, ori.getOrDefault(c, 0) + 1);
        }

        // 定义双指针 l 和 r, l 是左边界,r 是右边界
        int l = 0, r = -1;
        // 初始化最小长度 len 为一个较大的值,并定义答案的左右边界
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        int sLen = s.length();

        // 移动右指针 r 来扩展窗口
        while (r < sLen) {
            ++r;
            // 如果当前字符在 t 中出现过,则将其加入当前窗口 cnt 字典
            if (r < sLen && ori.containsKey(s.charAt(r))) {
                cnt.put(s.charAt(r), cnt.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;
                }
                // 尝试缩小窗口,即移动左指针 l
                if (ori.containsKey(s.charAt(l))) {
                    cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
                }
                ++l;
            }
        }
        // 如果找到了满足条件的最小子串,返回它;否则返回空字符串
        return ansL == -1 ? "" : s.substring(ansL, ansR);
    }
    public boolean check() {
    // 遍历 ori 字典的每一个键
    for (Character key : ori.keySet()) {
        // 获取 ori 中当前键对应的值,即 t 中该字符的数量
        Integer val = ori.get(key);

        // 如果 cnt 中该字符的数量小于所需数量,返回 false
        if (cnt.getOrDefault(key, 0) < val) {
            return false;
        }
    }
    // 如果所有字符都满足条件,返回 true
    return true;
   }
}

getOrDefault(c, 0) 方法

getOrDefault 是 Java Map 接口中的一个方法,用来从映射(字典)中获取指定键的值。如果该键存在于映射中,则返回对应的值;如果该键不存在,则返回一个默认值。

方法签名

V getOrDefault(Object key, V defaultValue) 

参数

  key:要获取值的键。

  defaultValue:当键不存在时返回的默认值。

返回值

        如果 key 存在,则返回与 key 关联的值。

        如果 key 不存在,则返回 defaultValue

示例

假设有一个 Map

Map<Character, Integer> map = new HashMap<>();
map.put('A', 1);
  1. map.getOrDefault('A', 0):返回 1,因为键 'A' 在 map 中存在,且对应的值为 1
  2. map.getOrDefault('B', 0):返回 0,因为键 'B' 不存在,返回默认值 0

getOrDefault 与 get 的主要区别

  1. 默认值处理

    • getOrDefault 在键不存在时会返回一个用户指定的默认值。
    • get 在键不存在时会返回 null
  2. 代码简洁性

    • 使用 getOrDefault 可以避免显式的空值检查,从而使代码更简洁。例如,如果用 get,你可能需要手动处理 null 值:
Integer value = map.get('B');
if (value == null) {
    value = 0;  // 或者其他默认值
}

 使用 getOrDefault 可以直接得到一个合理的默认值:

Integer value = map.getOrDefault('B', 0);

      3. 防止空指针异常

  • 使用 getOrDefault 可以有效避免空指针异常,因为它确保在键不存在时返回的值不是 null,而是用户指定的默认值。
  • 使用 get 时,如果不进行 null 检查,可能会因为直接操作 null 导致空指针异常。

总结

  • getOrDefault(c, 0):在 Map 中获取键 c 的值,如果不存在该键,则返回默认值 0。它的优势是可以简化代码,避免 null 检查,并且安全地处理不存在的键。
  • get(c):在 Map 中获取键 c 的值,如果不存在该键,则返回 null。使用时需要注意处理 null,以避免空指针异常。

Integer 

Integer 本质上是一个对象,可以为其赋值 null,也可以用来存储从 -2^312^31 - 1 范围内的任何整数值。这使得 Integer 能够在各种场合使用,特别是在需要对象的地方。

标签:练习题,10,默认值,leetcode76,返回,子串,getOrDefault,null,窗口
From: https://blog.csdn.net/2302_78946634/article/details/141857603

相关文章

  • (D卷,100分)- 堆栈中的剩余数字(Java & JS & Python&C&C++)
    题目描述向一个空栈中依次存入正整数,假设入栈元素n(1<=n<=2^31-1)按顺序依次为nx…n4、n3、n2、n1,每当元素入栈时,如果n1=n2+…+ny(y的范围[2,x],1<=x<=1000),则n1~ny全部元素出栈,重新入栈新元素m(m=2*n1)。如:依次向栈存入6、1、2、3,当存入6、1、2时,栈底......
  • CF 2100-2400 data structures 乱做
    CF2002ECosmicRays\(\star\)顺着询问想增加二元组\((a,b)\)的影响。只需要考虑它的合并情况,即尾部什么时候会出现数字\(b\),而总时间可以看作是最后一个尾部的存在时间,所以我们只需要关心尾部用栈维护尾部的数值和存在时间(不难发现这是一个单调栈)vector<pair<LL,int>>s;......
  • 算法:当一系列数据经过四舍五入后,总和不再等于100%时
    当一系列数据经过四舍五入后,总和不再等于100%时,这通常是由于四舍五入过程中产生的累积误差所导致的。为了处理这个问题,我们可以采用以下几种方法:1.重新分配误差步骤:计算四舍五入后总和与100%的差值。确定一个或多个需要调整的数据点,这些点可以是原始数据中相对不那么重要的......
  • AURIX™ Development Studio1.10.2(ADS)安装使用教程
    零、介绍AURIX™DevelopmentStudio是Infineon为TriCore™-basedAURIX™microcontroller系列车规单片机设计的一款免费IDE(集成开发环境),基于EclipseIDE开发。其包含了C编译器、TASKING调试器、多核调试器、iLLD库等功能。用户可通过AURIX™DevelopmentStudio-InfineonT......
  • 章10——面向对象编程(高级部分)——两种单例模式
    代码如下://单例模式//instance--实例//该篇中记录了饿汉模式和懒汉模式publicclassHungryMan{publicstaticvoidmain(String[]args){Single01.say();Single02.say();}}classSingle01{//只能有instance这一个实例。privateS......
  • java实现的开源mocker造数神器,10分钟可完成千万级别数据的造数-入门篇
    java实现的开源mocker造数神器,10分钟可完成千万级别数据的造数-入门篇如果你还在为数据库表造数烦恼?如果你还在造数上花费一天、一周、甚至更多的时间……也许Mocker(模客)能帮你排忧解难。造数是一件令人头疼、繁琐而又无趣的事情,但有些时候它又是开发过程中不可避免的一个阶段......
  • 【Python插件入门】第10篇(完结篇):插件常用工具类分享
    【Python插件入门】第10篇(完结篇):插件常用工具类分享原创金蝶云·星空-BOS平台金蝶云·星空-基础架构金蝶云·星空-学习笔记金蝶云·星空-协同开发更多 CQ周玉立已关注149人赞赏了该文章 1.8万次浏览 未经作者许可,禁止转载编辑于2022年08月22日09:......
  • IEC101、IEC103、IEC104、Modbus报文解析工具
    一、概述国际电工委员会第57技术委员会(IECTC57)1995年出版IEC60870-5-101后,得到了广泛的应用。为适应网络传输,2000年IECTC57又出版了IEC60870-5-104:2000《远东设备及系统第5-104部分:传输规约-采用标准传输协议集的IEC60807-5-1网络访问》。为规范该标准的国内应用,全国电......
  • Python的10个文件对比与合并高效策略
    文末赠免费精品编程资料~~在日常编程或数据分析工作中,经常需要处理多个文件的对比与合并任务。Python因其强大的文件处理能力和丰富的库支持,成为了处理这类任务的理想选择。下面,我们将逐步探索10种高效的文件对比与合并策略,每一步都配有详细的代码示例和解释。1.基础文件读......
  • Day14|第六章 二叉树 part02| 226.翻转二叉树| 101. 对称二叉树| 104.二叉树的最大深
    226.翻转二叉树(递归只能前序或者后序,中序不行)classSolution{publicTreeNodeinvertTree(TreeNoderoot){if(root==null)returnnull;swap(root);invertTree(root.left);invertTree(root.right);//swap(root);......