题目描述
给定两个字符串 source 和 target.
求 source 中最短的包含 target 中每一个字符的子串.
样例1
输入: source = "abc", target = "ac"
输出: "abc"
样例2
输入: source = "adobecodebanc", target = "abc"
输出: "banc"
解释: "banc" 是 source 的包含 target 的每一个字符的最短的子串.
样例3
输入: source = "abc", target = "aa"
输出: ""
解释: 没有子串包含两个 'a'.
解题思路
使用同向双指针模板。
targetHash 里存了 target 里每个字符和对应的次数次数。
hash 里存了当前 i ~ j 之间的字符和对应的出现次数。
当 hash 里包含了所有 targetHash 里的字符和其对应出现次数的时候,就是满足条件的字符串。
java题解
public class Solution {
public String minWindow(String ss , String tt) {
char[] s = ss.toCharArray();
char[] t = tt.toCharArray();
if (t.length == 0) {
return "";
}
int[] cntS = new int[256]; // number of appearances for each character in the window
int[] cntT = new int[256]; // how many times each character appears in T
int K = 0; // number of T's unique chracters
for (int i = 0; i < 256; ++i) {
cntS[i] = cntT[i] = 0;
}
for (char c : t) {
++cntT[c];
if (cntT[c] == 1) {
++K;
}
}
// abccba ==> K=3
int now = 0; // number of T's unique characters the window contains
// when now == K, we're good
int ansl = -1, ansr = -1;
int l, r = 0;
for (l = 0; l < s.length; ++l) { // main pointer, st
// insert into window
while (r < s.length && now < K) {
++cntS[s[r]];
// phase jump
if (cntS[s[r]] == cntT[s[r]]) {
++now;
}
++r;
}
if (now == K) {
// this window is good
if (ansl == -1 || r - l < ansr - ansl) {
ansl = l;
ansr = r;
}
}
// remove from window
--cntS[s[l]];
if (cntS[s[l]] == cntT[s[l]] - 1) {
--now;
}
}
// s[l...(r-1)]
if (ansl == -1) {
return "";
}
else {
return ss.substring(ansl, ansr);
}
}
}
C++题解
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> mp;
for (char now : t) {
mp[now] ++;
}
int count = mp.size();
int j = 0;
int ans = INT_MAX;
string res;
for (int i = 0; i < s.size(); i++) {
while(count != 0 && j < s.size()) {
mp[s[j]]--;
if (mp[s[j]] == 0) {
count--;
}
j++;
if (count == 0) {
break;
}
}
if (count == 0 && j - i< ans) {
ans = j - i;
res = s.substr(i, j - i);
}
if(mp[s[i]] == 0) {
count++;
}
mp[s[i]]++;
}
return res;
}
};
python题解
class Solution:
def minWindow(self, source , target):
if source is None:
return ""
targetHash = self.getTargetHash(target)
targetUniqueChars = len(targetHash)
matchedUniqueChars = 0
hash = {}
n = len(source)
j = 0
minLength = n + 1
minWindowString = ""
for i in range(n):
while j < n and matchedUniqueChars < targetUniqueChars:
if source[j] in targetHash:
hash[source[j]] = hash.get(source[j], 0) + 1
if hash[source[j]] == targetHash[source[j]]:
matchedUniqueChars += 1
j += 1
if j - i < minLength and matchedUniqueChars == targetUniqueChars:
minLength = j - i
minWindowString = source[i:j]
if source[i] in targetHash:
if hash[source[i]] == targetHash[source[i]]:
matchedUniqueChars -= 1
hash[source[i]] -= 1
return minWindowString
def getTargetHash(self, target):
hash = {}
for c in target:
hash[c] = hash.get(c, 0) + 1
return hash