题目描述
给出两个字符串 S 和 T,要求在O(n)的时间复杂度内,在 S 中找出最短的,包含 T 中所有字符的子串。
例如:
S ="XDOYEZODEYXNZ"
T ="XYZ"
找出的最短子串为"YXNZ"
注意:
如果 S 中没有包含 T 中所有字符的子串,返回空字符串 “”;
满足条件的子串可能有很多,但是题目保证满足条件的最短的子串唯一。
示例
输入:
"XDOYEZODEYXNZ","XYZ"
输出:
"YXNZ"
这道题的思路是:
1) begin开始指向0, end一直后移,直到begin - end区间包含T中所有字符。
记录窗口长度d
2) 然后begin开始后移移除元素,直到移除的字符是T中的字符则停止,此时T中有一个字符没被
包含在窗口,
3) 继续后移end,直到T中的所有字符被包含在窗口,重新记录最小的窗口d。
4) 如此循环知道end到S中的最后一个字符。
时间复杂度为O(n)
参考代码
public String minWindow ( String S, String T) {
int map[ ] = new int [ 128 ] ;
for ( int i = 0 ; i < T. length ( ) ; i++ ) {
map[ T. charAt ( i) ] ++ ;
}
int begin = 0 , end = 0 ;
int d = Integer. MAX_VALUE;
int counter = T. length ( ) ;
int head = 0 ;
while ( end < S. length ( ) ) {
if ( map[ S. charAt ( end) ] > 0 ) {
counter-- ;
}
map[ S. charAt ( end) ] -- ;
end++ ;
while ( counter == 0 ) {
if ( end - begin < d) {
head = begin;
d = end - head;
}
if ( map[ S. charAt ( begin) ] == 0 ) {
counter++ ;
}
map[ S. charAt ( begin) ] ++ ;
begin++ ;
}
}
return d == Integer. MAX_VALUE ? "" : S. substring ( head, head + d) ;
}