(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;
}
}