1. 程式人生 > >[Leetcode] Substring with concatenation of all words 串聯所有單詞的子串

[Leetcode] Substring with concatenation of all words 串聯所有單詞的子串

一聲 count 博客 oot 之間 back 空格 理解 是不是

You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.

For example, given:
S:"barfoothefoobarman"
L:["foo", "bar"]

You should return the indices:[0,9].
(order does not matter).

題意:給定一字符串S,幾個長度相同的單詞,讓我們找到串聯單詞的所有起始位置,單詞串中,單詞串聯的順序不管,且之間都沒有空格每個單詞串只出現一次。

與題目解答無關:我是把題目做完一遍以後,再在博客上進行整理的,結果發現這道題一下子沒有想出來,看以前的做過的答案,才把思路理清楚的,但是很尷尬的是,不知道以前是不是我自己做出來的,很大可能上不是,這道題的參考網站也恰好沒有留下記錄,所以要是大夥知道這題的原出處,跟我說一聲,我標明引用哈。

思路:這道題用到兩個哈希表,第一個哈希表先把所有的單詞放進去。然後從頭開始遍歷目標串S(跳出循環的條件是,當S中剩下的字符個數小於L中單詞總的長度時),針對每個字符 i,都以其為起始點在目標串S中取長度為m(單個單詞的長度),循環的總長度是n*m(L中單詞的總長度)放入第二個哈希表中,然後看S中的這個長度為m的單詞是否在單詞串L存在,若存在,還要繼續考慮相同單詞是否僅出現一次,如果多了,也跳出循環。代碼如下:

 1 class Solution {
 2 public:
 3     vector<int> findSubstring(string S, vector<string> &L) 
 4     {
 5         vector<int> res;
 6         if(S.empty() || L.empty())  return res;
 7        
 8         unordered_map<string,int> m1;
 9         for(auto &a:L)
10             m1[a]++;
11 12 int n=L.size(),m=L[0].size(),len=S.size(); 13 14 for(int i=0,j;i<=len-n*m;++i) 15 { 16 unordered_map<string,int> m2; 17 18 for(j=i;j<i+n*m;j+=m) 19 { 20 string tem=S.substr(j,m); 21 m2[tem]++; 22 if( !m1.count(tem) || m2[tem] > m1[tem]) 23 break; 24 } 25 if(j>=i+m*n) 26 res.push_back(i); 27 } 28 return res; 29 } 30 };

關於網上的令一種時間復雜度為O(n)的解答,我後續給出自己的理解。這裏給出參考地址。

[Leetcode] Substring with concatenation of all words 串聯所有單詞的子串