滑动窗口解法:
- 这个题能够做的出来,完全取决与东哥的教导,这是java版本的,但是核心的思路都是一样的,大同小异
思路分析:
基本的框架搭建,不是很困难,但是有很多需要考虑的边界值问题确实值得人深入研究一下
基本的框架,也就是两个map的字典,两个指针都指向数组的头节点,记录一个有效值来 写一个valid来记录符合字典字符的数量,如果valid == need.size()就说明现在的字符串已经完全匹配完成,可以对左指针进行缩进,
用start来记录开始的索引值,用len来记录最小的子串长, 将right和left 与len进行比较,对边界的值进行更新 valid其实就是对左值循环的一个判定条件,当valid != need.size()的时候,就说明现在已经匹配不上了,right要接着往下跑了, 这里的设计还是比较巧妙的,如果need字典中包含有左边的这个字符,更新windows字典,如果这两个字典中的有效值都是一样的话,这下子left++了 有效值就少一,windows就要重新更新他的字典.
class Solution {
public String minWindow(String s, String t) {
char[] sArr = s.toCharArray();
char[] tArr = t.toCharArray();
Map need = new HashMap<>();
Map windows = new HashMap<>();
for (char c :tArr) {
need.put(c,need.getOrDefault(c,0) + 1);
}
int left = 0;
int right = 0;
int valid = 0;//表示窗口中满足need条件的字符个数,如果valid和need.size()相同,就说明已经全部覆盖结束了子串
int start = 0;//最优解的起点
int len = Integer.MAX_VALUE;
while (right < sArr.length) {
//开始滑动
char c = sArr[right];
right++;
//进行窗口的一系列更新
if (need.containsKey(c)) {
windows.put(c,windows.getOrDefault(c,0) + 1);
if (windows.get(c).equals(need.get(c))) {
valid++;//这个东西其实就是need字典里面有效字符的数量
}
}
//判断左侧的窗口是否需要缩进
while (valid == need.size()) {
if (right - left < len) {
start = left;
len = right - left;
}
//d是需要移除的字符串
char d = sArr[left];
left++;
if (need.containsKey(d)) {
if (windows.get(d).equals( need.get(d))) {
valid--;
}
windows.put(d, windows.get(d) - 1);
}
}
}
return len == Integer.MAX_VALUE? "" : s.substring(start,start + len);
}
}



