算法-滑动窗口的应用
#最小覆盖字串问题
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
解题思路:
- 1.在字符串S中使用双指针中的左右指针技巧,初始化left=right=0,把索引闭区间【left,right】称为一个窗口;
- 2.不断增加right指针扩大窗口【left,right】,直到窗口中的字符串符合要求(包含了T中的所有的字符串);
- 3.此时,应该停止增大right,转而不断增大left指针缩小窗口【left,right】,直到窗口中的字符串不再符合要求。同时,每次增加left,都要更新一轮结果。
- 4.重复第2、3步,直到right到达了字符串S的尽头。
java代码
import java.util.HashMap;
import java.util.Map;
public class MinWindow {
public String slideWindow(String s,String t)
{
int left=0,right=0;
int start=0,minLen=Integer.MAX_VALUE;
int match = 0;
Map<Character,Integer> needs = new HashMap<>();
Map<Character,Integer> windows = new HashMap<>();
for(int i=0;i<t.length();i++)
{
needs.put(t.charAt(i),needs.getOrDefault(t.charAt(i), 0)+1);
}
while(right<s.length())
{
char c = s.charAt(right);
if(needs.containsKey(c))
{
windows.put(c, windows.getOrDefault(c, 0)+1);
if(needs.get(c).equals(windows.get(c)))match++;
}
right++;
while(match==needs.size())
{
if(right-left<minLen)
{
start = left;
minLen = right -left;
}
char cc = s.charAt(left);
if(needs.containsKey(cc))
{
windows.put(cc, windows.get(cc)-1);
if(windows.get(cc)<needs.get(cc))match--;
}
left++;
}
}
return minLen==Integer.MAX_VALUE?"":s.substring(start,start+minLen);
}
public static void main(String[] args) {
String s = "EBBANCF";
String t ="ABC";
MinWindow test = new MinWindow();
System.out.println(test.slideWindow(s, t));
}
}