LeetCode之最小覆盖子串 -- 滑动窗口

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。

  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。
解题思路

这道题可以用滑动窗口来解决,当窗口中的子串包含t中的所有字符时,计算当前窗口的长度,和原来窗口比较,最后返回最小的窗口中的字符串

1.定义left,right初始值都为0,count表示有效字符的个数,count表示有效字符的种类

定义hash1 表示窗口中的字符串,hash2 表示 t 的字符

首先将 t 中的字符根据键值对放到 hash2 中

移动right,并将right指向的字符放到 hash1 中,放到 hash1之后判断 hash1.get(right) 是否等于 hash2.get(right),如果相等,则是有效字符,count++,不相等则是无效字符

2.直到 count == hash2.size(),此时计算窗口的长度,并与原来长度比较,选较小的,然后将窗口的左右下标存到临时变量里面

3.然后移动left,移动前判断 hash1.get[left] 是否等于 hash2.get(left),如果相等,则证明当前是有效字符,count--,否则count不变。

然后hash.get(left)-- ,left++。

left 一直移动到下一次hash1.get(left) == hash2.get(left)

4.重复步骤1、2、3直到right到达最后

代码

当使用hashMap的接口时,LeetCode上最后一个会通不过,这是因为

java中使用Map时,里面的类型时Integer,因为Integer是对象,所以会缓存频繁使用的数值,范围是-128~127,在这个范围内的数会直接返回缓存值。超过了会new一个对象,所以在get的时候使用 .intValue()即可避免这种情况

hash2.put(t.charAt(i),hash2.getOrDefault(t.charAt(i),0).intValue()+1);

这个问题困扰了我将近4个小时的时间,希望看到这里的小伙伴可以避免出现这个问题

public String minWindow(String s, String t) {
        int left = 0;
        int right = 0;
        int count = 0;//表示当前有效字符
        HashMap<Character,Integer> hash1 = new HashMap<>();
        HashMap<Character,Integer> hash2 = new HashMap<>();
        int len = Integer.MAX_VALUE;//当前最小的窗口
        int tmpl = -1;//暂存最小窗口的left下标


        //将t存放到hash2
        for (int i = 0;i<t.length();i++){
            hash2.put(t.charAt(i),hash2.getOrDefault(t.charAt(i),0).intValue()+1);
        }


        while (right<s.length()){

            char charR = s.charAt(right);
            hash1.put(charR,hash1.getOrDefault(charR,0).intValue()+1);//将right指向的字符存到hash1
            if (hash1.get(charR).intValue() == hash2.getOrDefault(charR,0).intValue()){
                //此时是有效字符
                count++;
            }
            right++;

            //窗口成立时
            while (count == hash2.size()){
                //先更新一下窗口
            if(right-left < len){
                len = right-left;
                tmpl = left;

            }

                //移动left指针,不成立

                if (hash1.get(s.charAt(left)).intValue() == hash2.getOrDefault(s.charAt(left),0).intValue()){
                    count--;
                }
                hash1.put(s.charAt(left),hash1.get(s.charAt(left)).intValue()-1);
                left++;
            }


        }
        //最后返回 tmpl 和 tmpr之间的数
//        char[] str1 = new char[len];
        if (tmpl == -1){
            return new String();
        }

        return s.substring(tmpl,tmpl+len);

}

//大佬的代码
public String minWindow1(String ss, String tt) {
    char[] s = ss.toCharArray();
    char[] t = tt.toCharArray();
    int[] hash1 = new int[128];//用数组模拟哈希表
    int kinds = 0;//标记t中有多少种字符
    for (char ch:t){
        if (hash1[ch]==0){
            kinds++;
        }
        hash1[ch]++;
    }
    int[] hash2 = new int[128];


    int minlen = Integer.MAX_VALUE;
    int begin = -1;

    for (int left = 0,right = 0,count = 0;right<s.length;right++){
        char in = s[right];
        hash2[in]++;
        if (hash2[in]==hash1[in]) count++;

        while (kinds==count){
            if (right-left+1<minlen){
                begin=left;
                minlen = right-left+1;
            }
            char out = s[left];
            left++;
            if (hash2[out]==hash1[out]){
                count--;
            }
            hash2[out]--;

        }

    }
    if (begin == -1){
        return new String();
    }else {
        return ss.substring(begin,begin+minlen);
    }



}

很抱歉,由于优快云知道是一个文本AI助手,无法提供实时操作系统的安装指导。但是我可以给你提供一些基本的信息来帮助你安装nvidia-smi。 首先,Ubuntu是一个流行的Linux操作系统,而arm64是指适用于64位ARM架构的版本。要在Ubuntu arm64上安装nvidia-smi,你需要确保你的设备支持NVIDIA显卡,并且已经安装了适当的驱动程序。 以下是一些大致的步骤来安装nvidia-smi: 1. 确保你的设备上已经安装NVIDIA显卡,并且已经连接到互联网。 2. 打开终端,可以通过按下Ctrl+Alt+T来快速打开终端。 3. 添加NVIDIA的软件源。可以使用以下命令将其添加到你的系统中: ``` sudo add-apt-repository ppa:graphics-drivers/ppa ``` 4. 更新软件包列表。运行以下命令来更新软件包列表: ``` sudo apt update ``` 5. 安装适当的NVIDIA驱动程序。运行以下命令来安装最新的NVIDIA驱动程序: ``` sudo apt install nvidia-driver-<version> ``` 注意:将`<version>`替换为你想要安装的驱动程序版本号。 6. 安装nvidia-smi。运行以下命令来安装nvidia-smi: ``` sudo apt install nvidia-utils-<version> ``` 注意:将`<version>`替换为你想要安装nvidia-utils版本号。 7. 安装完成后,你可以通过在终端中运行以下命令来验证nvidia-smi是否安装成功: ``` nvidia-smi ``` 这些是大致的步骤,具体的安装过程可能会因为你的设备和操作系统版本而有所不同。建议你在安装之前查阅官方文档或者相关的社区讨论来获取更详细的指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值