【题目】
就是给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str里包含{a,b,c}的最短子串。要求O(n)。
【例子】
字符集是a,b,c,字符串是abdcaabcx,则最短子串为abc。
【分析】
有题意可知,满足要求的字符串只需要包括字符集中的所有字符,并没有顺序要求
当然最容易想到的是做一个字符匹配的过程,但题目要求查找次数为O(n),在思考了几种解决方法后,觉得下面的方案能够达到要求,虽然需要一些额外的空间。
下面我给出自己的解决方案,难免有遗漏的地方,如果路过的朋友有更好的方法,希望不吝赐教
1. 将字符集 (char_set )里的字符存储于一个 Hash_table 中,key 为字符本身,值为该字符所在位置,初始化为 -1,遍历 str 的时候,每遇见一个字符,就更新Hash_table
2. 设置额外变量用于记录查找成功的子字符串的最小长度,和子字符串的开头,结尾位置
3. 开始遍历 str,执行以下操作:
a) sum; // 用于记录 str 中包含了字符集中的字符个数, 如果 sum 等于字符集大小则执行以下程序,否则继续遍历直到满足条件为止
b) front, end; // front,end 分别存放最小子字符串的首末索引
c) for cur_char in str; // 用于记录遍历 str 时的当前字符
如果 cur_char 在字符集 char_set 中,则 Hash_table[cur_char] = str.index(cur_char) // str.index(cur_char) 将cur_char的索引记录
_f = min(Hash_table); // 找出 Hash_table 的最小值
_e = max(Hash_table); // 找出 Hash_table 的最大值
if ( _e - _f ) < min{
min = (_e - _f);
front = _f;
end = _e;
}
d) if sum < size(char_set) // 判断字符串 str 查找是否成功, sum 记录了 str 中包含了几个存在于 char_set 中的字符
return False;
else:
return str[front, end]; // 返回从 front 到 end 位置的子字符串