字串的視窗滑動問題
阿新 • • 發佈:2019-01-10
問題:一個字串S(暫時只考慮小寫字母),選擇S中包含26種英文字母的最短子串,如果不包含則返回空字元
分析:雙指標,動態維護一個區間。尾指標不斷往後掃,當掃到有一個視窗包含了所有26種英文字母的字串後,再收縮頭指標,直到不能再收縮為止。最後記錄所有可能的情況中視窗最小的。
分析:雙指標,動態維護一個區間。尾指標不斷往後掃,當掃到有一個視窗包含了所有26種英文字母的字串後,再收縮頭指標,直到不能再收縮為止。最後記錄所有可能的情況中視窗最小的。
程式碼示例:
#include <algorithm> #include <string> #include <iostream> using namespace std; const int UPPERALPHA_MAX = 26; class Solution { public: int appeared_count[UPPERALPHA_MAX]; public: //判斷是否已找到包含26種英文字母的字串 bool ContainAllAlpha(){ for(int i=0;i<26;i++){ if(appeared_count[i]<=0) return false; } return true; } //尋找符合條件的最小子串 string minWindow(string S) { if (S.empty()) return ""; if (S.size() < 26) return ""; fill(appeared_count, appeared_count + UPPERALPHA_MAX, 0); size_t minWidth = INT_MAX, min_start = 0; // 視窗大小,起點 int wnd_start = 0; //尾指標不斷往後掃 for (size_t wnd_end = 0; wnd_end < S.size(); wnd_end++) { appeared_count[S[wnd_end]-'a']++;//統計當前各英文字母出現的次數 //當ContainAllAlpha()第一次為true後,其後的判斷均為ture,後面程式執行的目的是找出最短的子串 if(ContainAllAlpha()){ //如果為true則包含了所有的26個英文字母 while(true){ //如果重複出現了,可以後移 if(appeared_count[S[wnd_start]-'a']>1){ appeared_count[S[wnd_start]-'a']--; wnd_start++; } else //只出現了一次,停止後移 break; } //找出最短子串,更新最短長度,和最短長度的起點 if (minWidth > (wnd_end - wnd_start + 1)) { minWidth = wnd_end - wnd_start + 1; min_start = wnd_start; } } } if(minWidth!=INT_MAX) return S.substr(min_start, minWidth); else return ""; } }; int main(){ string s="aabcdefghhhiijkijkjkijkkklmnopqrstuvzzzwxyzzcbabcdefghijklmnopqrstuvwxxyz"; Solution solution; cout<<solution.minWindow(s)<<endl; }
輸出結果為:abcdefghijklmnopqrstuvwxxyz