题解 | #最小覆盖子串#
最小覆盖子串
https://www.nowcoder.com/practice/c466d480d20c4c7c9d322d12ca7955ac
import java.util.*;
public class Solution {
/**
*
* @param S string字符串
* @param T string字符串
* @return string字符串
*/
/**
思路:使用双指针 left 和 right
使用两个map 分别表示当前窗口中的字符统计window 和 需要的字符统计need
然后 right 一直右移 直到当前window中包含我们所需要的need
即window中的字符统计 和 need中的字符统计相等为止
此时左移 选出尽可能短的符合要求的window 然后记录下来 直至不符合要求为止
然后再次右移 直到当前window中包含我们所需要的need
此时再次左移 选出尽可能短的符合要求的window 然后记录下来 直至不符合要求为止
。。。。
重复上面操作直至 right 超出范围
*/
public String minWindow (String S, String T) {
// write code here
String res = S;
boolean flag = false;
int n = S.length() - T.length();
//如果S的长度小与T 那么S一定不包含T
if(n < 0 ) return "";
//记录当前 窗口中的每个字符的个数
HashMap<Character,Integer> window = new HashMap<>();
//记录T中我们所需要的每个字符的个数
HashMap<Character,Integer> need = new HashMap<>();
//初始化window中每个字符为0
for(int i = 0 ; i < S.length() ; i++){
char c = S.charAt(i);
if(!window.containsKey(c)){
window.put(c,0);
}
}
//根据T初始化need中所需要的每个字符的统计
for(int i = 0 ; i < T.length() ; i++){
char c = T.charAt(i);
if(!need.containsKey(c)){
need.put(c,1);
}else{
need.put(c,need.get(c)+1);
}
}
//定义双指针
int left = 0;
int right = 0;
//定义 一个start 和一个 len 来唯一确定一个字符串
int start = 0;
int len = Integer.MAX_VALUE;
// 表示当前子串s 和 目标串T的匹配程度 (错误)当match == T.length 时匹配
// (正确)当match == need.size()
int match = 0;
while(right < S.length()){
while(match != need.size() && right < S.length()){
char c = S.charAt(right);
//如果整个字符是属于T中的
if(need.containsKey(c)){
window.put(c,window.get(c)+1);
//如果当前need中的c的个数刚好符合要求
//这里 如果window中的c多了 也不会增加match
if(window.get(c) == need.get(c)){
match ++;
}
}
right++;
}
//此时window中已经包含T
while(match == need.size()){ //只要window中的字符串包含S
//这里记录 当前最短合规字符串window
if(right - left < len){
len = right - left;
start = left;
}
char c = S.charAt(left);
//如果left这个字符是当前所被需要的
if(need.containsKey(c)){
window.put(c,window.get(c) -1);
//去除window中的字符影响到了window包含T
if(window.get(c) < need.get(c)){
match--;
}
}
left++;
}
}
return len == Integer.MAX_VALUE?"":S.substring(start,start+len);
}
}
查看13道真题和解析

拼多多集团-PDD公司福利 817人发布