一、題目分析
分析:就是在S中找出包括T的所有字符的最小窗口 ,要求時間複雜度是O(N)
所以有了之前滑動窗口的概念,這個題會好理解一點
值得注意的是
數量足夠:就是當前窗口中,begin位置的字符出現至少兩次,那麼爲了達到最小,自然就可以想到要把begin向右移動一位
來自下面博主的文字:
字符串和哈希表的問題。hashmap來存儲t字符串中個字母元素的出現次數,left right記錄當前子字符串的左右下標值,minminleft minright 變量存儲當前子字符串的最小長度以及左右下標。首先從前向後遍歷字符串,找到包含t中元素的子字符串,遍歷的同時記得更新hashmap中的字母元素次數的個數,每出現一次對應-1,同時count++,在count++的時候要注意: aedbbac 找abc 時, b連續出現過兩次,在count++的時候只在b出現的第一次++, 第二次不+,因爲我們只需要一個b。然後就是left向後收縮,right向後擴展,left向後收縮也就是left++的一個過程,去掉無用字符,每去掉一個字符的時候要對應判斷一下是否是t中元素,將hashmap中的頻率更新,以及count--,在count--的時候需要注意,即使當前刪減的字符是t中元素,但是它在hashmap中的計數次數是否是>=0, 也就是它是否重複出現比如上一步驟的例子: aedbbac 找abc 時, 顯然當left指向第一個b時,hashmap中要更新,但是count不要--。之後就是不斷更新min和minleft minright。
---------------------
作者:Pi_dan
來源:CSDN
原文:https://blog.csdn.net/qq_38595487/article/details/80388100
二、java代碼
class Solution {
public String minWindow(String s, String t) {
String string = "";
//hashmap來統計t字符串中各個字母需要出現的次數
HashMap<Character,Integer> map = new HashMap<>();
for (char c : t.toCharArray())
map.put( c, map.containsKey(c) ? map.get(c)+1 : 1);
//用來計數 判斷當前子字符串中是否包含了t中全部字符
int count = 0;
//記錄當前子字符串的左右下標值
int left = 0;
int right = 0;
//記錄當前最小子字符串的大小以及第一最後字符的下標值
int min = Integer.MAX_VALUE;
int minLeft = 0;
int minRight = 0;
for (; right < s.length() ; right++) {
char temp = s.charAt(right);
if (map.containsKey(temp)){//向後遍歷出所包含t的字符串
count = map.get(temp) > 0 ? count+1 : count;
map.put(temp,map.get(temp)-1);
}
while (count == t.length()){//得出一個符合條件的子字符串
if (right-left < min){//更新min minLeft minRight 信息
min = right - left;
minLeft = left;
minRight = right;
}
char c = s.charAt(left);
if (map.containsKey(c)){//向左收縮 判斷所刪減的字符是否在map中
if (map.get(c) >= 0)count --;//count--時需要判斷一下是否需要--
map.put(c,map.get(c)+1);
}
left++;
}
}
return min == Integer.MAX_VALUE ? "" : s.substring(minLeft,minRight+1);
}
}