【leetcode】Minimum Window Substring

來源:互聯網
上載者:User

標籤:hash   生活   工作   面試題   leetcode   

問題:給定兩個字串,S,T,返回S中包含T中所有字元的最短的字串,若不存在,則返回"".時間複雜度為O(n)。例如:S = "ADOBCODEBANC"          T = "ABC"         返回BANC生活情境:把問題具體化現實化一點。有n層樓,每層樓裡放有一個物品,現在老闆給你一個物品清單,裡面是要你集齊的物品,你可以乘坐電梯,但是電梯只停一次,停在哪一層,就從哪一層開始向樓上搜集物品,至於要在那層停電梯,由你自己選擇。這裡我們當然選擇即能集齊物品回去交差又能保證爬的樓梯最少的方法。分析:

以我們列舉的生活情境為例,我們在具體做這件事的時候,肯定不會拿著老闆給的類似T中:A物品 B物品 A物品 C物品 這麼二的清單,而是對物品做統計,產生這樣的需求清單:
物品A:X件
物品B:Y件
物品C:Z件
而在尋找的過程中,我們還需要一份已收集清單,就是目前已經找到的每個物品的資訊,其形式與上面列舉的一致。那麼這些資訊怎麼來儲存呢,我們總是希望對給定的物品,在O(1)的時間內找出對應的數值資訊,所以要用hash table。
我們開始在起始樓層(下電梯的樓層)向上尋找,遇到一個物品,我們看下是否是我們需要的,若是,則收集,並更改已收集清單相應物品的數量上加1。若不是,則跳過,繼續向樓上搜集。看到這裡我們就發現了問題,因為我們看到物品是需要的就收集它,並更改已收集表,那麼我們怎麼判斷我們已經完成了收集工作了呢?比較兩個表中對於的項,已收集項都大於等於需求的時候?但這樣要進行比較,不能在O(1)的時間得到明確的判斷,所以我們還需要一個變數,來記錄到目前為止,收集到的”有效“的物品數,何為有效物品,比如需求裡A:3,B:2,假設A的數量已經是3,當再次遇到A時,雖然A是需求清單裡需要的,但是已經有3個了,滿足要求了,現在遇到的A就不能算作有效物品,你現在需要做的是去收集除A以外其他物品。當有效物品數與需求清單中的總物品數相等的時候,我們就說我們的收集工作完成了。
但是這時你又會想,有沒有更好的選擇,比如你是從1樓開始收集的,收集到10樓將物品收集完畢,從2樓或者更高的樓層開始收集是不是也能完成任務?這樣就可以少爬幾層樓梯。這就要判斷1樓的物品性質了,假如1樓的物品不是需要的,當然可以直接從2樓開始,亦或者,雖然1樓的物品是需要的,但是2樓也有這個物品,而且從2樓開始,這個物品總是也滿足要求。那麼就可以從2樓開始,依次2樓,3樓,直到不能精簡,這就是當前的一個精簡視窗,也就是不包含子視窗的視窗。但這個就是最小的嗎?不一定,因為可能從11樓開始,到13樓就收集齊備了。所以這個尋找的過程要進行到最後。每次找到新的視窗,跟目前最小的比較,更新最小視窗。

實現://code
string minWindow(string S, string T) {int N = S.size();int M = T.size();int minWindowLen = INT_MAX;//hash table init all 0s//used to statistic the number of each letter needed.int needToFind[256] = {0};for (int i = 0; i < M; ++i)needToFind[T[i]]++;//hash table init all 0s//used to record the number of each letter has found. int hasFind[256] = {0};//use to record the total letters we has found.//if it equal to T.size(), it means we get a window.int count = 0;// end used to find the letters needed in T.// start used to drop the redundant letters to cut short the window.int start, end;//min_start and min_end recored the optimal resolve.int min_start = 0;int min_end = INT_MAX;for (start = 0, end = 0; end < N; ++end){if( 0 == needToFind[ S[end] ])//not neededcontinue;hasFind[ S[end] ]++;if(hasFind[ S[end] ] <= needToFind[ S[end] ])count++;//find a windowif(count == M){//judge whether the window can be cut short, for example, //the letter indicated by start is not needed or redundant. while ( 0 == needToFind[ S[start] ] || hasFind[S[start]] > needToFind[S[start]]){if(hasFind[S[start]] > needToFind[S[start]])//redundanthasFind[S[start]]--;++start;}int windowLen = end - start + 1;if (windowLen < minWindowLen){minWindowLen = windowLen;min_start = start;min_end = end;}}}if(min_end == INT_MAX)return "";return S.substr(min_start, min_end - min_start + 1);}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.