和substring with concatenation of all words类似的解法,仍然是双指针的,维护basemap和currmap和一个counter,但是指针移动的策略略有不同,在之前一题中,我们找的是一块区域,区域里面是有string array里所有的string组成的,也就是说不允许不在array里的string出现,也不许超出数量的string存在。但是在这一题中,根据题意,不在T里面的字符也是可以出现的,而且也容许超出某个字符在T里面数量的字符出现。所以根据右指针的移动,左指针移动的策略是:
- 如果right指向的字符不在T里,什么也不做
- 如果right指向的字符在T里,更新currmap,如果char c在currmap里的数量小于basemap,count++,如果count > T.length(),右移左指针,移动左指针的条件是,如果left指向的字符不在T里或者currmap里的数量超了basemap中的数量,就左移,直到停下为止,同时注意更新currmap,之后看情况更新应该返回的结果,然后为了让程序可以继续正确地进行下去,我们在左移left一位,使得count--,类似回到右移左指针之前的情况,然后更新map
每个char被扫2次,时间复杂度O(n),代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Solution { | |
public String minWindow(String S, String T) { | |
if (S == null || T == null) | |
return ""; | |
int len1 = S.length(), len2 = T.length(); | |
if (len2 > len1) | |
return ""; | |
HashMap<Character, Integer> baseMap = new HashMap<Character, Integer>(); | |
for (int i = 0; i < len2; i++) { | |
if (!baseMap.containsKey(T.charAt(i))) | |
baseMap.put(T.charAt(i), 1); | |
else | |
baseMap.put(T.charAt(i), baseMap.get(T.charAt(i)) + 1); | |
} | |
HashMap<Character, Integer> currMap = new HashMap<Character, Integer>(); | |
int count = 0, left = 0, min = Integer.MAX_VALUE, start = -1; | |
for (int right = 0; right < len1; right++) { | |
char curr = S.charAt(right); | |
if (baseMap.containsKey(curr)) { | |
if (!currMap.containsKey(curr)) | |
currMap.put(curr, 1); | |
else | |
currMap.put(curr, currMap.get(curr) + 1); | |
if (currMap.get(curr) <= baseMap.get(curr)) | |
count++; | |
//move left pointer as right as possible | |
if (count == len2){ | |
//discard redundant chars | |
while(!currMap.containsKey(S.charAt(left)) || currMap.get(S.charAt(left)) > baseMap.get(S.charAt(left))) { | |
if(currMap.containsKey(S.charAt(left))) { | |
currMap.put(S.charAt(left), currMap.get(S.charAt(left)) - 1); | |
if (currMap.get(S.charAt(left)) == 0) | |
currMap.remove(S.charAt(left)); | |
} | |
left++; | |
} | |
if (right - left + 1 < min) { | |
min = right - left + 1; | |
start = left; | |
} | |
//move left one step, continue | |
currMap.put(S.charAt(left), currMap.get(S.charAt(left)) - 1); | |
if (currMap.get(S.charAt(left)) == 0) | |
currMap.remove(S.charAt(left)); | |
left++; | |
count--; | |
} | |
} | |
} | |
return start == -1? "": S.substring(start, start + min); | |
} | |
} |
No comments:
Post a Comment