题目描述
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
思路
使用滑动窗口,知道使用滑动窗口,但是是看了答案才知道该怎么写代码的,怎么知道哈希里的每个元素都出现了呢,使用一个count;而且这个count不能遇见一个出现在HashMap里的字符就减一,要保证确实是还缺少的才能减,条件是hm.get© > 0
class Solution {
public String minWindow(String s, String t) {
//把字符串t放在HashMap里面
HashMap<Character,Integer> hm = new HashMap<>();
for(int i = 0;i < t.length();i++){
char c = t.charAt(i);
hm.put(c,hm.getOrDefault(c,0)+1);
}
int left = 0;
int right = 0;
int count = t.length();
int minlen = Integer.MAX_VALUE;
String res = "";
while(right < s.length()){
char c = s.charAt(right);
if(hm.containsKey(c)){
//表明hm.get(c) > 0此时count包含有它
if(hm.get(c) > 0) count --;
hm.put(c,hm.get(c)-1);
}
//当左边不是t中的元素,或者,最右边的元素和左边的元素相同的时候
while(left <= right && (!hm.containsKey(s.charAt(left)) || hm.get(s.charAt(left)) < 0)){
if(hm.containsKey(s.charAt(left)))
hm.put(s.charAt(left),hm.get(s.charAt(left))+1);
left++;
}
if(count == 0 && minlen > right-left+1){
minlen = right-left+1;
res = s.substring(left,right+1);
}
right++;
}
return res;
}
}
总结:
与滑动窗口相关的题做得并不多,手很生,不太会写,要多加练习
滑动窗口题目:
-
无重复字符的最长子串
-
串联所有单词的子串
-
最小覆盖子串
-
至多包含两个不同字符的最长子串
-
长度最小的子数组
-
滑动窗口最大值
-
字符串的排列
-
最小区间
-
最小窗口子序列