【LeetCode---76】最小覆盖字串---滑动窗口
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Solution2 {
//创建两个Map,用来统计源字符串和目标字符串中各个字符的数目
Map<Character, Integer> ori = new HashMap<>();
Map<Character, Integer> tar = new HashMap<>();
public String minWindow(String source, String target) {
//把target这个字符串的各个字符都放入到tarmap中
for (int i = 0; i < target.length(); i++) {
tar.put(target.charAt(i), tar.getOrDefault(target.charAt(i), 0) + 1);
}
//初始化需要的各个指针与变量
//left,right为窗口的左右边界
int left = 0, right = -1;
//len为窗口的最小值,ansL与ansR为最终需要返回的字串的下标,最终我们要通过String.subString(ansL,asnR)返回
int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
int slen = source.length();
//窗口滑动的过程
while (right < slen) {
right++;
//如果滑动的过程当中找到了一个与目的串中的字符匹配的,那么就把这个字符放入到ori源串中
if (right < slen && tar.containsKey(source.charAt(right)))
ori.put(source.charAt(right), ori.getOrDefault(source.charAt(right), 0) + 1);
//如果当前这个窗口可以满足目标窗口的字符数量
//那么更新答案区间,并且缩小窗口
while (valid() && left <= right) {
//更新答案区间
if (right - left + 1 < len) {
len = right - left + 1;
ansL = left;
ansR = left + len;//subString()函数是左闭右开的
}
//缩小窗口
if (tar.containsKey(source.charAt(left))){
ori.put(source.charAt(left), ori.getOrDefault(source.charAt(left), 0) - 1);
}
left++;
}
}
return ansL == -1 ? "" : source.substring(ansL, ansR);
}
//检查源字符串是否满足目标字符串的要求
private boolean valid() {
Iterator iter = tar.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry =(Map.Entry) iter.next();
Character key =(Character) entry.getKey();
Integer value = (Integer) entry.getValue();
if (ori.getOrDefault(key, 0) < value)
return false;
}
return true;
}
}