Given strings S
and T
, find the minimum (contiguous) substring W
of S
, so that T
is a subsequence of W
.
If there is no such window in S
that covers all characters in T
, return the empty string ""
. If there are multiple such minimum-length windows, return the one with the left-most starting index.
Example 1:
Input: S = "abcdebdde", T = "bde" Output: "bcde" Explanation: "bcde" is the answer because it occurs before "bdde" which has the same length. "deb" is not a smaller window because the elements of T in the window must occur in order.
Note:
- All the strings in the input will only contain lowercase letters.
- The length of
S
will be in the range[1, 20000]
. - The length of
T
will be in the range[1, 100]
.
----------------------------------------------------------------------
非常好的一道题目。
双指针解法:双指针,把T覆盖以后,两个字符串的指针同时向前移,一直找到T耗尽为止。。。然后下一轮再从上次匹配到位置的下一个开始。
class Solution:
def minWindow(self, S, T):
slen,tlen,i,j = len(S),len(T),0,0
maxL,res = slen+1,""
while (i < slen):
if (S[i] == T[j]):
j += 1
if (j == tlen):
j -= 1
end = i #bug1: end=j
while (j >= 0):
if (T[j] == S[i]):
j -= 1
i -= 1
i += 1
if (end-i+1 < maxL):
maxL = end-i+1
res = S[i:end+1]
i += 1
return res
BFS解法:被覆盖的字符串T中的第一个字符T[0]会匹配S中的某几个字符,如果把匹配到的这几个位置记下来。到了T[1],T[2]..T[n-1]依次往后推进之前的匹配位置,最终比一下最短那个,典型的BFS思路
class Solution(object):
def minWindow(self, S, T):
slen,tlen,c,n = len(S),len(T),0,1
layers = [[(i,i) for i in range(slen) if S[i] == T[0]],[]] #(start,end)
for i in range(1,tlen):
tch = T[i]
for first,last in layers[c]:
tgt = S.find(tch, last+1)
if (tgt != -1):
layers[n].append((first, tgt))
if (not layers[n]):
return ""
layers[c].clear()
c,n = n,c
maxL,res = slen + 1,""
for first, last in layers[c]:
if (last-first+1 < maxL):
maxL = last-first+1
res = S[first:last+1]
return res
NextMatch数组解法:其实就是把上述解法的S.find替换成O(1)的复杂度,和 https://blog.csdn.net/taoqick/article/details/106699543 这篇中求NextMatch的思路完全一样,而且这里的写法更简洁:
class Solution(object):
def minWindow(self, S, T):
slen,tlen,c,n = len(S),len(T),0,1
nxt = [-1 for i in range(26)]
nxt_arr = [None for i in range(slen)]
for i in range(slen-1, -1, -1):
ch_idx = ord(S[i])-ord('a')
nxt[ch_idx] = i
nxt_arr[i] = tuple(nxt)
layers = [[(i,i) for i in range(slen) if S[i] == T[0]],[]] #(start,end)
for i in range(1,tlen):
tch = T[i]
for first,last in layers[c]:
#tgt = S.find(tch, last+1)
tgt = nxt_arr[last+1][ord(tch)-ord('a')] if last+1<slen else -1
if (tgt != -1):
layers[n].append((first, tgt))
if (not layers[n]):
return ""
layers[c].clear()
c,n = n,c
maxL,res = slen + 1,""
for first, last in layers[c]:
if (last-first+1 < maxL):
maxL = last-first+1
res = S[first:last+1]
return res