1. 程式人生 > >leetcode 76.Minimum Window Substring

leetcode 76.Minimum Window Substring

leetcode 76.Minimum Window Substring

題目:

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string ""
    .
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

解法:

這個題應該是每日一題開始做到現在難度最大的一個。

這個題跟一般的字串匹配問題不太一樣,是要讓你在母字串 S 中找出能夠包含所給字元序列 S(其字元順序可以亂序)的最小子序列。

那麼首先我們要解決兩個問題:

  • 找出符合要求的字元序列
  • 簡化我們找到的字元序列,讓其長度最小

對於第一個問題,我們採用遍歷的方法就可以,比如序列S = “ACBDHJEABDJ”

T = “ABJ” ,我們可以找出兩個複合要求的序列 output1 = ACBDHJoutput2 = ABDJ,從第二個要求中我們應當選擇output2 ;

對於第二個問題,我使用的方法就是在第一個問題的基礎上進行簡化,比如刪去末尾或者開頭無用的字元,但是我們需要注意我們不能刪去夾雜在已求出的序列之間的字元,同時也可以刪去重複出現的待匹配字元。

在具體實現上,我們可以考慮使用雜湊的方法,開闢陣列存放待求字串中每個字母出現的個數進而保證我們在找到已經給定的數目的某個字元時候,在後面優化時候可以壓縮序列,同時也可以保證我們判斷已經結束了優化與搜尋。


程式碼:

class
Solution { public: string minWindow(string S, string T) { int hasFound[256] = {0}; int needToFind[256] = {0}; int windowBegin = 0; int windowEnd = 0; int minwindowBegin = 0; int minWindowEnd = 0; //NOTE1: int minLength = S.length(); //minWindow("a", "a"): expected return "a", actual wrong answer ""; int minLength = INT_MAX; string minStr = ""; for (int i =0; i < T.length(); ++i){ needToFind[T[i]]++; } int begin = 0, end = 0, count = 0; //string str1 = "ADOBECODEBANC"; //string str2 = "ABC"; for (begin = 0, end = 0; end < S.length();++end) { if (needToFind[S[end]]<0) continue; hasFound[S[end]]++; if (hasFound[S[end]] <= needToFind[S[end]]) count++; if (count >= T.length()) { while (needToFind[S[begin]] == 0 || hasFound[S[begin]] > needToFind[S[begin]]) { //NOTE2: two level logica if (hasFound[S[begin]] > needToFind[S[begin]]) { hasFound[S[begin]]--; } begin++; } windowBegin = begin; windowEnd = end; if (windowEnd - windowBegin + 1 < minLength) { minLength = windowEnd - windowBegin + 1; windowEnd = end; windowBegin = begin; minStr = S.substr(windowBegin, windowEnd - windowBegin + 1); } } } return minStr; } };