您的位置:首页 > 其它

Coding Puzzels - 64 最小的窗口子字符串

2016-06-13 23:36 204 查看
给定一个字符串S和一个字符串T,求S中的最小的窗口,其中包含了T中的字符。算法的复杂度为O(n)。

例如,S="ADOBECODEBANC", T="ABC"。最小的窗口是“BANC”。注意如果不存在覆盖了T中的所有的字符的窗口,返回空字符串。如果有多个这样的窗口,确保S中总有一个唯一的最小窗口。

package com.algo.coding.puzzles;

import java.util.HashMap;

public class MinWindow64 {

public String minWin(String resource, String target){
HashMap expectCountHs = new HashMap();
HashMap appearCountHs = new HashMap();
int minV = Integer.MAX_VALUE;
int start = 0;
int end = 0;
int winStart = 0;
for(int i = 0; i < target.length(); i++){
char c = target.charAt(i);
Object countObj = expectCountHs.get(c);
int count;
if(countObj != null){
count = (int) countObj;
count ++;
}else{
count = 1;
}
expectCountHs.put(target.charAt(i), count);
}
int appearChars = 0;
for(int winEnd = 0; winEnd < resource.length(); winEnd++){
char c = resource.charAt(winEnd);
int expectCount = this.getCount(expectCountHs, c);
/*
* only关心Target里有的字符
*/
if(expectCount > 0){
int appearCount = this.getCount(appearCountHs, c);
appearCount++;
appearCountHs.put(c, appearCount);
/*
* 当出现了期待的字符,会计算期待字符的个数。
*/
if(expectCount >= appearCount){
appearChars++;
}
}

/*
* appearCountHs 代表win start 和 win end 区间内字符串出现的次数。
* (在target里有的字符会比较存在的次数和target里的次数,严格等于appearCountHs。 在target里没有的字符,有可能出现-1,这不影响。)
* appearCountHs (A=1 B=1 C=1), expectCountHs (A=1 B=1 C=1), winStart = 0, winEnd = 5 没有运行 while
* appearCountHs (A=2 B=2 C=1), expectCountHs (A=1 B=1 C=1), winStart = 0, winEnd = 10 运行完下面的while,变成 winStart = 5, winEnd = 10
* appearCountHs (A=1 B=1 C=2), expectCountHs (A=1 B=1 C=1), winStart = 5, winEnd = 12
* 当C的appearCount > expectCount, winStart ++, 其他字符expectCount == 0 运行完下面的while,变成 winStart = 9, winEnd = 12
* */
char startChar = resource.charAt(winStart);
int startAppearCount = this.getCount(appearCountHs, startChar);
int startExpectCount = this.getCount(expectCountHs, startChar);
/*
* 当期待区间内出现所有期待的字符,才运行。去掉这个条件,minV最小会是1。
*/
if(appearChars == target.length()){
while(startAppearCount > startExpectCount || startExpectCount == 0){
startAppearCount --;
appearCountHs.put(startChar, startAppearCount);
winStart ++;
startChar = resource.charAt(winStart);
startAppearCount = this.getCount(appearCountHs, startChar);
startExpectCount = this.getCount(expectCountHs, startChar);
}
if(minV > winEnd - winStart + 1){
minV = winEnd - winStart + 1;
start = winStart;
end = winEnd;
}
// return resource.substring(start, end);
}
}
return resource.substring(start, end+1);

}

public int getCount(HashMap hs, char c){
Object obj = hs.get(c);
int count = 0;
if(obj != null){
count = (int) obj;
// count ++;
}
return count;
}

public static void main(String[] args) {
// TODO Auto-generated method stub
// String resource = "ADOBECODEBANC";
// String target = "ABC";
// String resource = "abccbaddac";
// String target = "abcd";
String resource = "aabcadbbbcca";
String target = "abcd";
MinWindow64 minWin = new MinWindow64();
System.out.println(minWin.minWin(resource, target));;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: