题目描述: 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。 注意: 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。 如果 s 中存在这样的子串,我们保证它是唯一的答案。 示例 1: 输入:s = “ADOBECODEBANC”, t = “ABC” 输出:“BANC” 示例 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) 链接: https://leetcode-cn.com/problems/minimum-window-substring 解决方案: 思路: 滑动窗口,很NB的一种思想,设置两个指针 l 和 r 分别表示左边界和右边界,通过不断扩展和收缩窗口,就像一个窗口在字符串上游走一样,达到包含字符串 t 中所有元素的条件。
public static String minWindow(String s, String t) {
if (s == null || s.length() == 0 || t == null || t.length() == 0){
return "";
}
int[] need = new int[128];
for (int i = 0; i < t.length(); i++) {
need[t.charAt(i)]++;
}
int l = 0, r = 0, size = Integer.MAX_VALUE, count = t.length(), start = 0;
while (r < s.length()) {
char c = s.charAt(r);
if (need[c] > 0) {
count--;
}
need[c]--;
if (count == 0) {
while (l < r && need[s.charAt(l)] < 0) {
need[s.charAt(l)]++;
l++;
}
if (r - l + 1 < size) {
size = r - l + 1;
start = l;
}
need[s.charAt(l)]++;
l++;
count++;
}
r++;
}
return size == Integer.MAX_VALUE ? "" : s.substring(start, start + size);
}
|