76. minimum-window-substring
阿新 • • 發佈:2018-12-17
這道題細節處理起來還是有點難度,太不是難到沒有思路的那種。
題目大意:給定兩個字串,一個是原始匹配串,另一個是目標串,在匹配串中選尋找一個最短的字串,包含目標串的所有字元,重複情況要考慮。例如:abdccab 目標串是 abccd,則原始匹配串中最短的字串是dccab
思路,首先,並不是KMP求目標子串,條件沒有那麼嚴格,所以,先要記錄目標串中每個字元的個數。
其次,利用一前一後兩個指標分別表示視窗的左右兩個邊,當匹配串left和right中間的欄位沒有完全包含目標串中的所有字元,則right指標右移,否則,left指標左移,以獲得最小視窗。
需要注意的是,在視窗的滑動過程中,當某個字元出現在窗口裡面,則說明該字元已經被包含,相應的記錄值要減去1,如果left增加,某個字元從視窗中出去,則該字元的計數值要加1,表示該字元已經不在記錄中了。這塊說起來可能不要說清楚,看程式碼一下就明白了。
另外,這道題是用hash表來做是非常方便的,但是,告訴大家一個小技巧,所有的和字串相關的問題,凡是用到hash表做計數用的,都可以轉化為使用陣列。
以下是AC的程式碼:
class Solution { public: string minWindow(string s, string t) { vector<int> tmap(128, 0); for (char c : t) { ++tmap[c]; } string res = ""; int counts = 0, minwin = INT_MAX, left = 0; for (int i=0; i<s.size(); ++i) { --tmap[s[i]]; if (tmap[s[i]] >= 0) { ++counts; } while (counts == t.size()) { if (minwin > i-left+1) { minwin = i-left+1; res = s.substr(left, minwin); } if (tmap[s[left]] >= 0) { --counts; } ++tmap[s[left]]; ++left; } } return res; } };