今天在lintCode上做了一道题,感觉有必要将它记录下来。
1. 概览
(1).题意
给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。
(2).注意事项
如果在source中没有这样的子串,返回"",如果有多个这样的子串,返回长度最小的子串。(注意:lintCode上说的是起始位置最小,但是我认为它说错了)。
(3).说明
在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?--不需要。
(4).样例
给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解 "BANC"
2.解题思路
这道题的思路非常的简单,就是哈希表的操作。
首先,我们创建一个哈希表,遍历target字符串,更新每个字符的出现的次数;然后定义一个count变量,初始换为target字符串的长度。
其次,我们在遍历source字符串,更新哈希表。
我知道,这样说的话,肯定不好明白意思,接下来我贴代码,然后再详细的解释。
3.代码
public String minWindow(String source, String target) {
if (source.equals(target)) {
return target;
}
if (target.equals("") || source.equals("")) {
return "";
}
int [] map = new int[128];
int count = target.length();
int begin = 0;
int head = 0;
int end = 0;
int d = Integer.MAX_VALUE;
for (int i = 0; i < target.length(); i++) {
map[target.charAt(i)]++;
}
while (end < source.length()) {
if(map[source.charAt(end++)]-- > 0) {
count--;
}
while (count == 0) {
if (d > end - begin) {
d = end - begin;
head = begin;
}
if(map[source.charAt(begin++)]++ ==0) {
count++;
}
}
}
return d == Integer.MAX_VALUE ? "" : source.substring(head, head + d);
}
map[source.charAt(end++)]--就是用来更新我们的哈希表。但是这里为什么只有大于0时,count才减减?因为之后在大于0时,表示更新的字符才是target中的字符。
当count等于0时,source的begin~end的子串中含有全部target字符了。然后我们在更新head,如果d > end - end,head等于begin。
为什么map[source.charAt(begin++)]++ ==0时,count需要加加呢?因为在end ~ begin之间有可能出现了target的字符多次,我们需要更新begin,来调整距离,使得距离最小。