【題目】
就是給一個很長的字符串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 位置的子字符串