双指针最小覆盖子串(滑动窗口)(medium)
Posted 念奕玥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双指针最小覆盖子串(滑动窗口)(medium)相关的知识,希望对你有一定的参考价值。
若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。
leetcode 76最小覆盖子串
思路:
使用滑动窗口方法求解,即两个指针
l
l
l 和 r 都是从最左端向最右端移动,且
l
l
l的位置一定在r 的左边或重合。l和j窗口内包含的字符全涵盖t中的字符,则符合要求,记下此时窗口长度r-
l
l
l+1。从符合条件的长度中找出最小长度即可。
step1: l和r都指向字符串开头。
step2: 不断右移r,直到窗口内包含了t中所有字符,记录下此次窗口长度。
step3: 左移
l
l
l,判断移除的字符是否在t字符串内,若在,则继续右移l(step2),若不在,则记录此时窗口长度,并判断是不是当前最小长度(若是,则更新最小长度),继续左移l。
考虑到t中会有重复字符,所以使用map来记录t中的字符及其出现的个数。
因此,判断窗口内的字符是否都涵盖了t中所有字符串,也需要使用map来记录窗口内的字符及其个数。t中某字符出现的次数与窗口中出现次数一致,且t中字符种类个数(e.g. “abadac”为4个字符种类)与窗口中字符种类个数一致时,即认为窗口全涵盖了t中字符。
右移指针
l
l
l时,窗口中字符要做相应变化,且要判断t中是否含有从窗口中移除的字符,若没有,则无操作;若有,则需要比较该字符在窗口中的个数与t中的个数,若一致,则移除该字符后,窗口不满足全涵盖t。若不一致(只会是大于等于,因为只有窗口全涵盖t时才会让l右移),则不操作。
class Solution {
public String minWindow(String s, String t) {
//将要覆盖的字符串放到map中并记录每个字母出现的次数。
HashMap<Character,Integer> covered = new HashMap<>();
for(char ch:t.toCharArray()){
covered.put(ch,covered.getOrDefault(ch,0)+1);
}
//将窗口内的字符串放到map中并记录每个字母出现的次数。
HashMap<Character,Integer> window = new HashMap<>();
int left=0,right=0;//滑动窗口的左右指针
int len = Integer.MAX_VALUE;
int valid=0;//记录窗口中涵盖的t中字符串的个数(t中重复字符算一个)
int start=0;//子路最小子串的起始位置
//滑动部分逻辑
while(right<s.length()){
char c =s.charAt(right);
right++;
//右指针不断右移,只要有符合的字符valid就++,且该符合的字符放入到window中,并记录出现次数
if(covered.containsKey(c)){
window.put(c,window.getOrDefault(c,0)+1);
if(window.get(c).equals(covered.get(c))){
valid++;
}
}
//当 当前窗口字符串 涵盖 t中所有字符 时,记录长度,左指针右移
while(valid==covered.size()){
//记录当前窗口的长度
if(right-left<len){
start=left;
len=right-left;
}
char d = s.charAt(left);//即将移除出窗口的字符
//左指针右移
left++;
//若t中包含移除出窗口的字符d
if(covered.containsKey(d)){
//只有当窗口内字符d的数量等于字符串t中字符d的数量时,valid--
//当窗口内字符d的数量大于字符串t中字符d的数量时,valid不用改动,
//因为移除字符d后仍满足窗口内字符串全包含t
if(window.get(d).equals(covered.get(d))){
valid--;
}
//若t中不包含字符d,即使窗口左指针右移,窗口中包含的字符也不用移除,因为没影响。
// window.put(d,window.getOrDefault(d,0)-1);
}
//因为窗口左指针右移了,所以window中的字符要作相应变化
window.put(d,window.getOrDefault(d,0)-1);
}
}
return len==Integer.MAX_VALUE?"":s.substring(start,start+len);
}
}
以上是关于双指针最小覆盖子串(滑动窗口)(medium)的主要内容,如果未能解决你的问题,请参考以下文章