最小覆盖子串(Java)

(leetcode 76) 困难

题目要求

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

注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"

思路

注意,本题的 t 字符串可以包含多个相同的字符

建立两个HashMap。key为字符,value为字符的数量。
即:判断条件为,mapT的每个value是否小于等于对应的mapS的value

重要方法

//HashMap原始图操作
Set keySet()//返回所有key构成的Set集合
Collection values()//返回所有value构成的Collection集合
Set entrySet()//返回所有key-value对构成的Set集
    Entry getKey()
    Entry getValue()

//String常用方法
//String类的获取功能
int length() //获取字符串的长度。
char charAt (int index) //获取指定索引位置的字符
int indexOf (int ch) //返回指定字符在此字符串中第一次出现处的索引。
                       为什么这里是int类型,而不是char类型?
                       原因是: a和97其实都可以代表a
int indexof (String str) //返回指定字符串在此字符串中第一次出现处的索引。
String substring(int start) //从指定位置开始截取字符串,默认到末尾。
String substring(int start, int end) //从指定位置开始到指定位置结束截取字符串。
//String的转换功能:
byte[] getBytes () 					//把字符串转换为字节数组。
char[] toCharArray()  				//把字符串转换为字符数组。
static String valueOf (char[] chs) 	//把字符数组转成字符串。
static String valueOf (int i) 		//把int数据转成字符串。
//String类的替换功能:
String replace(char old, char new)
    String replace(String old,String new)
    String trim()						//去除字符串前后空格
    int compareTo(String str)			//按字典顺序比较两个字符串
    int compareToIgnoreCase(String stx)	//同上忽略大小写
//String类的判断功能:
    boolean endsWith(String suffix)		//测试此字符串是否以指定的后缀结束
    boolean startsWith(String prefix)	//测试此字符串是否以指定的前缀开始
    boolean contains(CharSequence s)	//当且仅当此字符串包含指定的char值序列时,返回true

代码

class Solution {
    Map<Character,Integer> mapS = new HashMap<Character,Integer>();
    Map<Character,Integer> mapT = new HashMap<Character,Integer>();

    public String minWindow(String s, String t) {
        for(int i = 0; i < t.length(); i ++) {
            mapT.put(t.charAt(i), mapT.getOrDefault(t.charAt(i), 0) + 1);
        }
        int l = 0;
        int r = 0;
        int minLength = s.length();
        int markL = -1;
        int markR = -1;

        while(r < s.length()) {
            //右滑动
            if(mapT.containsKey(s.charAt(r))) {
                mapS.put(s.charAt(r), mapS.getOrDefault(s.charAt(r),0) + 1);
            }
            r ++;

            //左滑动
            while(judge()) {
                if((r - l) <= minLength) {
                    minLength = r - l;
                    markL = l;
                    markR = r;
                }
                if(mapT.containsKey(s.charAt(l))) {
                    mapS.put(s.charAt(l), mapS.getOrDefault(s.charAt(l),0) - 1);
                }
                l ++;
            }
        }

        return markL == -1 ? "" : s.substring(markL,markR);
    }

    public boolean judge() {
        for(Character ch : mapT.keySet()) {
            if(mapT.get(ch) > mapS.getOrDefault(ch, 0)) return false;
        }
        return true;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值