题目描述
给你一个字符串 S、一个字符串 T 。请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入:S = “ADOBECODEBANC”, T = “ABC”
输出:“BANC”
提示:
- 如果 S 中不存这样的子串,则返回空字符串 “”。
- 如果 S 中存在这样的子串,我们保证它是唯一的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
思路
滑动窗,先向右扩张,直到包含T所有字符,然后收缩窗的左边,收缩到满足条件的最小子串,保存该串起始位置和长度,向后继续此操作。
class Solution {
public String minWindow(String s, String t) {
if(s.length() < t.length()){
return "";
}
int[] need = new int[128];
int[] have = new int[128];
for(int i = 0;i < t.length();i++){
need[t.charAt(i)]++;
}
int left = 0,right = 0,min = s.length()+1,start = 0,count = 0;
while(right < s.length()){
char tem = s.charAt(right);
if(need[tem] == 0){
right++;
continue;
}
if(have[tem] < need[tem]){
count++;
}
have[tem]++;
right++;
while(count == t.length()){
if(right - left < min){
start = left;
min = right - left;
}
char temLeft = s.charAt(left);
if(need[temLeft] == 0){
left++;
continue;
}
if(need[temLeft] == have[temLeft]){
count--;
}
have[temLeft]--;
left++;
}
}
if(min == s.length()+1) return "";
return s.substring(start,start+min);
}
}