76. Minimum Window Substring,minimumsubstring
76. Minimum Window Substring,minimumsubstring
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC"
.
Note:
If there is no such window in S that covers all characters in T, return the empty string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
题意:给定字符串s和t,求s包含t中所有字符的最小子串;s的子串不仅需要包含所有t中的字符,且字符数目同样要大于等于t中对于字符的数目。
这个题的思路在于“窗口”的移动 ,“窗口”指的是符合要求的s的子串,但不一定是最小的。
那么我们要做的就是先找到第一个符合要求的窗口,记录下窗口的长度,
例如S = "ADOBECODEBANC"
T = "ABC".
我们先找到第一个窗口"ADOBEC",记录下它的长度为6和起始下标0;
第二步删除窗口的第一个字符'A',然后找到第二个出现'A'的地方,这样我们就得到了第二个窗口"BECODEBA",记录下窗口的长度8,起始下标为3;
继续上述步骤,得到下一个窗口,"CODEBA",记录窗口长度6,起始下标5;
……
最后一个窗口"BANC",长度为4,起始坐标为9,
这样每个找到一个窗口就更新窗口长度和起始坐标,最后得到最小的窗口。
在解题过程中我们需要借助字典或者HashMap来记录字符出现的次数。
下面是方法具体实现的代码:
class Solution {
public String minWindow(String s, String t) {
if(s.isEmpty() || t.isEmpty())
return "";
int[] tt = new int[128]; //字典,以字符值作为下标,元素值为字符出现的次数
boolean[] b = new boolean[128]; //用来区分字符是否是字符串t中的
for(int i=0;i<t.length();i++){ //赋值
tt[t.charAt(i)]++;
b[t.charAt(i)] = true;
}
int left = 0; //窗口左端
int count = 0; //记录当前窗口中有多少个字符串t中的字符
int minLen = s.length()+1; //记录窗口最小长度
int minLeft = 0; //最小窗口起始下标
for(int i=0;i<s.length();i++){
if(b[s.charAt(i)]){
tt[s.charAt(i)]--;
if(tt[s.charAt(i)]>=0) //当小于0时,表示当前窗口的某个字符数目已经超过了t中该字符的数目,count值不变
count++;
}
while(count == t.length()){ //窗口锁定,记录窗口长度和起始下标
if(i-left+1 < minLen){
minLen = i-left+1;
minLeft = left;
}
if(b[s.charAt(left)]){
tt[s.charAt(left)]++;
if(tt[s.charAt(left)] > 0)
count--;
}
left++;
}
}
return minLen==s.length()+1 ? "" : s.substring(minLeft,minLeft+minLen);
}
}
这个方法中的2个数组可以用1个HashMap代替。另外解决这道题的这种窗口模型可以适用于很多种类似的情况。
相关文章
- 暂无相关文章
用户点评