Java代码
题干
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
想法
滑动窗口
Java代码
public class Solution {
public String minWindow(String s, String t) {
int sLen = s.length();
int tLen = t.length();
if (sLen == 0 || tLen == 0 || sLen < tLen) {
return "";
}
char[] charArrayS = s.toCharArray();
char[] charArrayT = t.toCharArray();
int[] tFreq = new int[128];
for (char c : charArrayT) {
tFreq[c]++;
}
// 滑动窗口内部还差多少 T 中的字符,对应字符频数超过不重复计算
int distance = tLen;
int minLen = sLen + 1;
int begin = 0;
int left = 0;
int right = 0;
// [left..right)
while (right < sLen) {
char charRight = charArrayS[right];
if (tFreq[charRight] > 0) {
distance--;
}
tFreq[charRight]--;
right++;
// System.out.println(distance + " " + s.substring(left, right));
while (distance == 0) {
// System.out.println("左边界收缩 " + distance + " " + s.substring(left, right));
// System.out.println(tFreq['A'] + "," + tFreq['B'] + "," + tFreq['C']);
if (right - left < minLen) {
minLen = right - left;
begin = left;
}
char charLeft = charArrayS[left];
tFreq[charLeft]++;
if (tFreq[charLeft] > 0) {
distance++;
}
left++;
}
}
if (minLen == sLen + 1) {
return "";
}
return s.substring(begin, begin + minLen);
}
}