/**
* Description:
* 描述
* 给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。
* <p>
* 如果在source中没有这样的子串,返回"",如果有多个这样的子串,返回起始位置最小的子串。
* <p>
* 说明
* 在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?
* <p>
* ——不需要。
* <p>
* 样例
* 给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解 "BANC"
* <p>
* <p>
* 题目:找到包含target串中所有字符的最小字串。
* <p>
* 思路:
* <p>
* 首先采用一个大小为256的数组充当hashmap的功能,记录tartget中字母出现次数。
* 算法流程如下:
* <p>
* 1. 先将target中所有的字符出现的次数保存到td数组中。
* 2. 遍历source数组,开始时start=0,i=0;
* <p>
* start记录当前字串的起点,i相当于当前字串的终点。
* <p>
* 用found表示当前字串中包含target中字符的数目,如果found=target.length()则表明当前字串包含了target中所有字符,如果满足,进入下一步。
* <p>
* 3. 将start后移,取出start前面多余的元素,已达到字串最小的目标。
* <p>
* 4.判断,如果当前字串小于历史搜到的最小字串,则将当前字串的长度,起始点,结束点都记录,更新。
* <p>
* 5.将start后移,寻找下一个字串。
* ---------------------
* 作者:cosmos_lee
* 来源:优快云
* 原文:https://blog.youkuaiyun.com/u012156116/article/details/80648698
* 版权声明:本文为博主原创文章,转载请附上博文链接!
*/
public class MixWindow {
public static String minWindow(String source, String target) {
// write your code here
if (Strings.isNullOrEmpty(source) || Strings.isNullOrEmpty(target)) {
return "";
}
char[] td = new char[256];
for (char tc : target.toCharArray()) {
td[tc]++;
}
char[] sd = new char[256];
int minLen = source.length();
int start = 0;
int first = -1, end = 0;
int found = 0; // 在source中发现了target中元素的数目
for (int i = 0; i < source.length(); i++) {
sd[source.charAt(i)]++;
if (sd[source.charAt(i)] <= td[source.charAt(i)]) {
found++;
}
if (found == target.length()) {
// 满足条件
// 处理1:start后移,删除无用元素
while (start <= i && sd[source.charAt(start)] > td[source.charAt(start)]) {
sd[source.charAt(start)]--;
start++;
}
// 处理2:如果比当前最小子串小,则更新
if (i + 1 - start <= minLen) {
minLen = i + 1 - start;
first = start;
end = i + 1;
}
sd[source.charAt(start)]--;
start++;
found--;
}
}
if (first == -1) {
return "";
} else {
return source.substring(first, end);
}
}
}
https://blog.youkuaiyun.com/u012156116/article/details/80648698