32. 最小子串覆盖
给定两个字符串 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'.
挑战
O(n) 时间复杂度
注意事项
-
如果没有答案, 返回 "".
-
保证答案是唯一的.
-
target 可能包含重复的字符, 而你的答案需要包含至少相同数量的该字符.
public class Solution {
/**
* @param source : A string
* @param target: A string
* @return: A string denote the minimum window, return "" if there is no such a string
*/
public String minWindow(String source, String target) {
// write your code here
if (source.contains(target)) return target;
String result = "";
int[] sour = new int[256];
int[] tar = new int[256];
for (int i = 0; i < target.length(); i++) {
char c = target.charAt(i);
tar[c]++;
}
int start = 0, end = 0, len = Integer.MAX_VALUE;
for (int i = 0; i < source.length(); i++) {
char c = source.charAt(i);
sour[c]++;
if (equalTwo(sour, tar)) {
end = i;
while (true) {
char ch = source.charAt(start);
if (sour[ch]-1 <tar[ch] ) {
break;
}
sour[ch]--;
start++;
}
if (end - start < len) {
len = end - start;
result = source.substring(start, end + 1);
// System.out.println(start+","+ end);
}
}
}
return result;
}
boolean equalTwo(int[] x, int[] y) {
for (int i = 0; i < x.length; i++) {
if (x[i] < y[i]) return false;
}
return true;
}
}
public class Solution {
/**
* @param source : A string
* @param target: A string
* @return: A string denote the minimum window, return "" if there is no such a string
*/
public String minWindow(String source, String target) {
// write your code here
if (source.contains(target)) return target;
String result = "";
HashMap<Character, Integer> hashMap = new HashMap<>();
for (int i = 0; i < target.length(); i++) {
char c = target.charAt(i);
if (hashMap.containsKey(c)) {
int num = hashMap.get(c);
num++;
hashMap.put(c, num);
} else {
hashMap.put(c, 1);
}
}
HashMap<Character, Integer> add = new HashMap<>();
int start = 0, end = 0 ,len=Integer.MAX_VALUE;
for (int i = 0; i < source.length(); i++) {
char c = source.charAt(i);
if (hashMap.containsKey(c)) {
if (add.containsKey(c)) {
int num = add.get(c);
num++;
add.put(c, num);
} else {
add.put(c, 1);
}
if (equalTwo(hashMap, add)) {
end = i;
while (true){
char ch = source.charAt(start);
if (hashMap.containsKey(ch)){
int num = add.get(ch);
num--;
int num2 = hashMap.get(ch);
if (num2>num){
break;
}
add.put(ch, num);
}
start++;
}
if (end-start<len){
len=end-start;
result = source.substring(start, end + 1);
// System.out.println(start+","+ end);
}
}
}
}
return result;
}
boolean equalTwo(HashMap<Character, Integer> hashMap1, HashMap<Character, Integer> hashMap2) {
// if (hashMap1.size() != hashMap2.size()) return false;
for (Map.Entry<Character, Integer> entry : hashMap1.entrySet()) {
// System.out.println(entry.getValue()+","+hashMap2.get(entry.getKey()));
if (hashMap2.get(entry.getKey())==null){
return false;
}else {
if (entry.getValue() > hashMap2.get(entry.getKey())) {
return false;
}
}
}
return true;
}
}