leetcode_76_最小覆盖子串

4 篇文章 0 订阅
4 篇文章 0 订阅

Question 76 Minimum Window Substring

在这里插入图片描述

一道偏难的leetcode题目,一开始看到题目的标题可能就会想到滑动窗口,且这种找字符串子串的题目,基本都会用到hashmap。但是一开始可能想不到很好的思路,若是采用暴力遍历法,那么获得所有字串需要的时间为O(n2),每一次还需要对比哈希表,那么时间复杂度直接就成了O(n3),时间复杂度太高,直接不予考虑。

直接上代码来解释

class Solution {
    public String minWindow(String s, String t) {
        //一个哈希表用来存储t字符串,一个用来存储当前窗口的字符
        Map<Character, Integer> tMap = new HashMap<>();
        Map<Character, Integer> windowMap = new HashMap<>();
         
        for(char c: t.toCharArray()) {
            tMap.put(c, tMap.getOrDefault(c, 0) + 1);
        }
        //关键来了,need指的是t哈希表里面的个数
        //have指的是窗口哈希表里面,有多少个字符满足了条件
        //举个例子,如果t哈希表是a=1, b=1, c=2,而窗口表格是
        // a=1, b=1那么have就是2
        int need = tMap.size(), have = 0;
        int left = 0, right = 0;
        int maxSize = Integer.MAX_VALUE;
        int start = -1, end = -1;
        while (right < s.length()) {
            char c = s.charAt(right);
            if (tMap.containsKey(c)) {
                windowMap.put(c, windowMap.getOrDefault(c, 0) + 1);
                if (windowMap.get(c).equals(tMap.get(c))) {
                    have++;
                }
            }
            //当满足条件的时候,从窗口的左侧逐渐剔除字符,缩短长度,直到不在包含所有t的字符串为止
            while(have == need) {
                if (right - left + 1 < maxSize) {
                    maxSize = right - left + 1;
                    start = left;
                    end = right;
                }
                char c2 = s.charAt(left);
                if (tMap.containsKey(c2)) {
                    windowMap.put(c2, windowMap.getOrDefault(c2, 0) - 1);
                    if (windowMap.get(c2).compareTo(tMap.get(c2)) < 0) {
                        have--;
                    }
                }
                left++;
            }
            right++;
        }
        return maxSize == Integer.MAX_VALUE ? "" : s.substring(start, end + 1);
    }
}

这里额外插一句,在进行Integer的大小比较的时候,需要使用equals方法,否则过不去几个特殊情况,原因涉及到jvm以及封装问题,这里就不展开了。另外因为这里用的都是Integer,为了严谨,使用了Integer自带的compareTo方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值