Question 76 Minimum Window Substring
一道偏难的leetcode题目,一开始看到题目的标题可能就会想到滑动窗口,且这种找字符串子串的题目,基本都会用到hashmap。但是一开始可能想不到很好的思路,若是采用暴力遍历法,那么获得所有字串需要的时间为O(n2),每一次还需要对比哈希表,那么时间复杂度直接就成了O(n3),时间复杂度太高,直接不予考虑。
直接上代码来解释
class Solution {
public String minWindow(String s, String t) {
//一个哈希表用来存储t字符串,一个用来存储当前窗口的字符
Map<Character, Integer> tMap = new HashMap<>();
Map<Character, Integer> windowMap = new HashMap<>();
for(char c: t.toCharArray()) {
tMap.put(c, tMap.getOrDefault(c, 0) + 1);
}
//关键来了,need指的是t哈希表里面的个数
//have指的是窗口哈希表里面,有多少个字符满足了条件
//举个例子,如果t哈希表是a=1, b=1, c=2,而窗口表格是
// a=1, b=1那么have就是2
int need = tMap.size(), have = 0;
int left = 0, right = 0;
int maxSize = Integer.MAX_VALUE;
int start = -1, end = -1;
while (right < s.length()) {
char c = s.charAt(right);
if (tMap.containsKey(c)) {
windowMap.put(c, windowMap.getOrDefault(c, 0) + 1);
if (windowMap.get(c).equals(tMap.get(c))) {
have++;
}
}
//当满足条件的时候,从窗口的左侧逐渐剔除字符,缩短长度,直到不在包含所有t的字符串为止
while(have == need) {
if (right - left + 1 < maxSize) {
maxSize = right - left + 1;
start = left;
end = right;
}
char c2 = s.charAt(left);
if (tMap.containsKey(c2)) {
windowMap.put(c2, windowMap.getOrDefault(c2, 0) - 1);
if (windowMap.get(c2).compareTo(tMap.get(c2)) < 0) {
have--;
}
}
left++;
}
right++;
}
return maxSize == Integer.MAX_VALUE ? "" : s.substring(start, end + 1);
}
}
这里额外插一句,在进行Integer的大小比较的时候,需要使用equals方法,否则过不去几个特殊情况,原因涉及到jvm以及封装问题,这里就不展开了。另外因为这里用的都是Integer,为了严谨,使用了Integer自带的compareTo方法。