力扣76.最小覆盖子串 | 双指针 | 重点
思考
这道题实在是写不出来,听了讲解,自己尝试敲代码,思路一团浆糊。标记标记标记重点题
右指针不断向右移动 扩展子串,左指针不断向右移 压缩子串
1.先利用右指针遍历 while(right < s.length()),先什么情况不考虑最后,肯定right++。
2.嵌套while(have == count),判断是否满足子串条件,满足以后移动左指针。
3.最后移动左指针,移动之前需要先保存当前左指针的情况并更新hash表。
代码
点击查看代码
class Solution {
public String minWindow(String s, String t) {
if(s.length() == 0 || t.length() == 0 || s.length() < t.length()){
return "";
}
Map<Character,Integer> mubiao = new HashMap<>();
Map<Character,Integer> hashtest = new HashMap<>();
for(int i = 0;i < t.length();i++){
mubiao.put(t.charAt(i),mubiao.getOrDefault(t.charAt(i),0) + 1);
}
int count = mubiao.size();//count统计字符种类的数量;
int have = 0;//have统计当前子串中满足t种字符的种类,仅仅当每个字符第一次大于等于mubiao哈希表中的value时++;
int left = 0,right = 0;
int resStart = 0,resLength = Integer.MAX_VALUE;//reslength = Math.min(reslength,curlength);
while(right < s.length()){
if(mubiao.containsKey(s.charAt(right))){//如果目标hashmap包含当前字符,就在hashtest里面存一下
hashtest.put(s.charAt(right),hashtest.getOrDefault(s.charAt(right),0)+1);
if(mubiao.get(s.charAt(right)).equals(hashtest.get(s.charAt(right)))){//如果次数相同,have++
have++;
}
}
while(have == count){//已满足子串条件;
if(right - left + 1 < resLength){//小于历史最大长度,更新
resLength = right - left + 1;
resStart = left;//记录当前窗口起点
}
//已找到满足子串,需要移动left指针,移动前需要查验当前left的字符是否是关键元素,并更改hashtest
if(mubiao.containsKey(s.charAt(left))){
hashtest.put(s.charAt(left),hashtest.get(s.charAt(left))-1);//因为已经满足数量,所以此时直接减1;
//减完再比较hashtest和mubiao的left,看是否冗余
if(hashtest.get(s.charAt(left)) < mubiao.get(s.charAt(left))){
have--;
}
}
//操作完一切移动left指针
left++;
}
right++;
}
if(resLength == Integer.MAX_VALUE) return "";
return s.substring(resStart,resStart + resLength);
}
}
浙公网安备 33010602011771号