您的位置:首页 > 其它

LintCode:M-最小子串覆盖

2017-08-28 20:41 435 查看
给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。


 注意事项


如果在source中没有这样的子串,返回"",如果有多个这样的子串,返回起始位置最小的子串。

您在真实的面试中是否遇到过这个题? 

Yes

说明

在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?
——不需要。

样例

给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解
 "BANC"

分析

利用字符串的特性,开辟两个128长度的字符空间来直接定位不同的字符,记录出现的次数

如果要节约空间的话,可以用开辟两个Hash

TC = O(n)

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_array(String source, String target) {
int ns = source.length();
int nt = target.length();
int[] countSor = new int[128];
int[] countTar = new int[128];
char[] sors = source.toCharArray();
char[] tars = target.toCharArray();

for(int i=0; i<nt; i++){
countTar[tars[i]]+=1;
}

int count=0;
int start=0, begin=-1, end=0, minLen=Integer.MAX_VALUE;
for(int i=0; i<ns; i++){
countSor[sors[i]]+=1;

if(countSor[sors[i]]<=countTar[sors[i]]){
count++;
}

if(count==tars.length){
//相当于把之前的出栈
//找到sor中国前面最开始的Tar中的字符
while(start<i && countSor[sors[start]]>countTar[sors[start]]){
countSor[sors[start++]]--;
}

if(i-start+1<minLen){
minLen = i-start+1;
begin = start;
end = i;
}

//找到了一个
//现在去掉一个,继续往后找下一个符合要求的
countSor[sors[start++]]--;
count--;
}
}

if(begin!=-1)
return source.substring(begin, end+1);
else
return "";
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息