题目
题目来自牛客NC28 最小覆盖子串
给出两个字符串 s 和 t,要求在 s 中找出最短的包含 t 中所有字符的连续子串。
例如:
输入:“XDOYEZODEYXNZ”,“XYZ”
返回值:“YXNZ”
注意:
如果 s 中没有包含 t 中所有字符的子串,返回空字符串 “”;
满足条件的子串可能有很多,但是题目保证满足条件的最短的子串唯一。
双指针思路
这里根据题目双指针这个知识点展开思考,这里以输入“XEZZXY”,"XZZ"为例,过程如图所示。
Java实现
import java.util.HashMap;
import java.util.Map;
/**
* NC28.最小覆盖子串
* @author Caven
* @date 2023/7/6 22:14
*/
public class MinimumCoveringSubstring {
public static void main(String[] args) {
System.out.println(minWindow("abcAbA", "AA"));
}
public static String minWindow (String S, String T) {
// write code here
if(T.length()>S.length()){
return "";
}
int left = 0;
int right = left+1;
int min = Integer.MAX_VALUE;
String res = "";
HashMap<Character,Integer> map = new HashMap<>();
for (int i = 0; i < T.length(); i++) {
char temp = T.charAt(i);
if (map.containsKey(temp)){
map.put(temp,map.get(temp)+1);
}else {
map.put(temp,1);
}
}
while (right<=S.length()){
String substring = S.substring(left, right);
if (substring.length()>=T.length()&&isContains(substring,map)){
if (substring.length()<min){
min = substring.length();
res = substring;
}
left++;
}else {
right++;
}
}
return res;
}
public static boolean isContains(String s,HashMap<Character,Integer> mapt){
HashMap<Character, Integer> map = new HashMap<>(mapt);
for (int i = 0; i < s.length(); i++) {
char temp = s.charAt(i);
if (map.containsKey(temp)){
map.put(temp,map.get(temp)-1);
}
}
for (Map.Entry<Character, Integer> entry : map.entrySet()) {
if (entry.getValue()>0){
return false;
}
}
return true;
}
}