题解 | #最小覆盖子串#

最小覆盖子串

http://www.nowcoder.com/practice/c466d480d20c4c7c9d322d12ca7955ac

题意整理

  • 给出两个字符串s和t,要求在s中找出最短的包含t中所有字符的连续子串。

方法一(暴力循环)

1.解题思路

  • 首先统计T中所有字符出现次数,记录在map1中。
  • 然后两层循环遍历S中所有连续子串,对每一个子串,统计字符出现次数,记录在map2中。
  • 每次判断某个子串是否包含t中所有字符,如果包含,则更新子串长度len和起始点start。

2.代码实现

import java.util.*;


public class Solution {
    /**
     * 
     * @param S string字符串 
     * @param T string字符串 
     * @return string字符串
     */
    public String minWindow (String S, String T) {
        //n为S的长度,m为T的长度
        int n=S.length();
        int m=T.length();
        //记录子串长度
        int len=10001;
        //记录子串起始点
        int start=0;
        //统计T中字符出现次数
        int[] map1=new int[128];
        for(int i=0;i<m;i++){
            map1[T.charAt(i)]++;
        }
        for(int i=0;i<n;i++){
            //统计子串字符出现次数
            int[] map2=new int[128];
            for(int j=i;j<n;j++){
                map2[S.charAt(j)]++;
                //如果合法,并且长度小于len
                if(match(map1,map2)&&len>j-i+1){
                    //更新len和起始点
                    len=j-i+1;
                    start=i;
                }
            }
        }
        return len==10001?"":S.substring(start,start+len);
    }
    
    //判断子串是否包含T中所有字符
    private boolean match(int[] map1,int[] map2){
        for(int i=0;i<128;i++){
            //只要某个字符,T中出现次数更多,则不合法
            if(map1[i]>map2[i]){
                return false;
            }
        }
        return true;
    }
}

3.复杂度分析

  • 时间复杂度:假设n为S的长度,m为T的长度,统计T中字符出现次数需要遍历整个T字符串,时间复杂度O(m)O(m)。两层循环枚举所有可能的连续子串,总共n(n+1)/2n*(n+1)/2个,match函数的复杂度为常数级别,所以时间复杂度为O(n2+m)O(n^2+m)
  • 空间复杂度:需要额外大小128的map1和map2数组,均为常数级别,所以空间复杂度是O(1)O(1)

方法二(双指针)

1.解题思路

  • 首先统计T中所有字符出现次数,记录在map中。
  • 定义两个变量l和r分别记录子串的起点和终点。定义一个变量count用于统计T中字符是否能在对应子串完全消除,如果能,则子串合法,否则,不合法。
  • 如果右边界对应字符次数大于0,说明需要消去当前字符,r右移,map对应次数减1,同时count减1。只要count为0时,说明字符全部消除掉,当前子串合法,跟新子串长度和起始点。如果左边界对应字符次数等于0,说明需要重新消去当前字符,l右移,右移之后,map对应次数加1,计数count也需要加1。

图解展示: alt

2.代码实现

import java.util.*;

public class Solution {
    /**
     * 
     * @param S string字符串 
     * @param T string字符串 
     * @return string字符串
     */
    public String minWindow (String S, String T) {
        //n为S的长度,m为T的长度
        int n=S.length();
        int m=T.length();
        //记录子串长度
        int len=10001;
        //记录子串起始点
        int start=0;
        //统计T中字符出现次数
        int[] map=new int[128];
        for(int i=0;i<m;i++){
            map[T.charAt(i)]++;
        }
        //滑动窗口的左右边界l和r,以及待消除的字符数量count
        int l=0,r=0,count=m;
        while(r<n){
            //如果出现次数大于0,说明需要消除,count减1
            if(map[S.charAt(r++)]-->0){
                count--;
            }
            //只要count为0,说明当前子串合法
            while(count==0){
                //如果长度小于len,则更新len和start
                if(len>r-l){
                    len=r-l;
                    start=l;
                }
                //如果左边界字符出现次数为0(要么小于0,要么等于0),则需要重新消除,后移l
                if(map[S.charAt(l++)]++==0){
                    //后移之后,count需加1
                    count++;
                }
            }
        }
        return len==10001?"":S.substring(start,start+len);
    }
    
}

3.复杂度分析

  • 时间复杂度:假设n为S的长度,m为T的长度,双指针移动过程中,每个字符最多遍历一次,所以时间复杂度为O(n+m)O(n+m)
  • 空间复杂度:需要额外大小128的map数组,为常数级别,所以空间复杂度是O(1)O(1)
xqxls的题解 文章被收录于专栏

牛客题解

全部评论
你这道题不对吧 我感觉差一步,就是那个while循环里面,有可能是ABXDOYEZ呢,map[A]的次数本来就是0,那么为啥还要加map[A]++,不对吧
点赞 回复 分享
发布于 2022-03-10 22:10

相关推荐

06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务