艰难的通过了,好多边缘条件,一开始还把realCount[S.charAt(first) - 'A']--写成了realCount[first - 'A']--,还有second到达字符串尾时,first还可以往前推的,如果total==targetTotal了。算法是参照leetcode论坛里的,两个指针。左右指针之间是满足条件的区间,判断条件是区间内的吻合值和需要的吻合值相同。注意:1.'A'小于'a';2. 两个指针的还是外面的大while和里面的两个小while。
在我的代码里是先动first再动second,看了参考的解法,先动second,到达total时再动first至可能的最右,是更简洁的解法。
参考:http://discuss.leetcode.com/questions/97/minimum-window-substring
public class Solution {
public String minWindow(String S, String T) {
// Start typing your Java solution below
// DO NOT write main() function
int targetCount[] = new int[256];
int realCount[] = new int[256];
int targetTotal = 0;
for (int i = 0; i < T.length(); i++)
{
targetCount[T.charAt(i) - 'A']++;
targetTotal++;
}
int first = 0;
int second = 0;
int total = 0;
int start = 0;
int end = 0;
int min = Integer.MAX_VALUE;
while (first < S.length())
{
if (total == targetTotal && total != 0) {
realCount[S.charAt(first) - 'A']--;
if (realCount[S.charAt(first) - 'A'] < targetCount[S.charAt(first) - 'A']) {
total--;
}
first++;
}
// move forward first
while (first < S.length() && targetCount[S.charAt(first) - 'A'] == 0) {
first++;
}
if (first >= S.length()) break;
if (second < first) second = first;
while (total < targetTotal && second < S.length())
{
if (targetCount[S.charAt(second) - 'A'] > 0) {
realCount[S.charAt(second) - 'A']++;
if (realCount[S.charAt(second) - 'A'] <= targetCount[S.charAt(second) - 'A']) {
total++;
}
}
second++;
}
if (total == targetTotal && total != 0) {
int dist = second - first;
if (dist < min)
{
min = dist;
start = first;
end = second;
}
}
if (second >= S.length() && total != targetTotal) break;
}
if (min == Integer.MAX_VALUE) return "";
else
return S.substring(start, end);
}
}
Python3。其实containsMap这个方法复杂了,可以用一个cnt记录多少个字符符合要求了(mapS[char] >= mapT[char]),这样当cnt < targetCnt的时候,就可以处理。
class Solution:
def containsMap(self, mapS, mapT): # whether s contains t
if len(mapS) == len(mapT):
for char in mapT:
if char not in mapS:
return False
if mapT[char] > mapS[char]:
return False
return True
return False
def minWindow(self, s: str, t: str) -> str:
mapT = {}
mapS = {}
for char in t:
if not char in mapT:
mapT[char] = 0
mapT[char] += 1
minLen = None
result = ''
i = j = 0
while i < len(s) and j < len(s):
while j < len(s) and not self.containsMap(mapS, mapT): # not enough
if s[j] in mapT: #
if s[j] not in mapS:
mapS[s[j]] = 0
mapS[s[j]] += 1
j += 1
while i < len(s) and self.containsMap(mapS, mapT): # enough
if minLen is None or j - i < minLen:
minLen = j - i
result = s[i : j]
if s[i] in mapS:
mapS[s[i]] -= 1
if mapS[s[i]] == 0:
del mapS[s[i]]
i += 1
return result