给定两个字符串 s
和 t
。返回 s
中包含 t
的所有字符的最短子字符串。如果 s
中不存在符合条件的子字符串,则返回空字符串 ""
。
如果 s
中存在多个符合条件的子字符串,返回任意一个。
注意: 对于 t
中重复字符,我们寻找的子字符串中该字符数量必须不少于 t
中该字符数量。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最短子字符串 "BANC" 包含了字符串 t 的所有字符 'A'、'B'、'C'
示例 2:
输入:s = "a", t = "a"
输出:"a"
示例 3:
输入:s = "a", t = "aa"
输出:""
解释:t 中两个字符 'a' 均应包含在 s 的子串中,因此没有符合条件的子字符串,返回空字符串。
提示:
1 <= s.length, t.length <= 105
s
和t
由英文字母组成
进阶:你能设计一个在 o(n)
时间内解决此问题的算法吗?
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public String minWindow(String s, String t) {
if (s == null || s.length() == 0 || t == null || t.length() == 0) {
return "";
}
int[] sArr = new int[52];
int[] tArr = new int[52];
for (char ch : t.toCharArray()) {
if (ch <= 'Z') {
tArr[ch - 'A']++;
} else {
tArr[26 + ch - 'a']++;
}
}
int start = 0;
int end = 0;
int minLen = Integer.MAX_VALUE;
String result = "";
while (end < s.length()) {
while (end < s.length()) {
char ch = s.charAt(end);
if (ch <= 'Z') {
sArr[ch - 'A']++;
} else {
sArr[26 + ch - 'a']++;
}
if (isMatch(sArr, tArr)) {
break;
}
end++;
}
if (end == s.length()) {
break;
}
while (isMatch(sArr, tArr)) {
if (end - start + 1 < minLen) {
minLen = end - start + 1;
result = s.substring(start, start + minLen);
}
char ch = s.charAt(start);
if (ch <= 'Z') {
sArr[ch - 'A']--;
} else {
sArr[26 + ch - 'a']--;
}
start++;
}
end++;
}
return result;
}
boolean isMatch(int[] sArr, int[] tArr) {
for (int i = 0; i < 52; i++) {
if (sArr[i] < tArr[i]) {
return false;
}
}
return true;
}
}
//leetcode submit region end(Prohibit modification and deletion)