目錄
滑窗思想:
在解決字符串子串問題時,可以採用滑窗的思想;
1,在字符串S中使用雙指針中左右指針技巧,初始化left = right = 0,把索引[left,right]成爲一個窗口
2,不斷增加right指針擴大窗口[left,right],直到窗口中字符串符合要求
3,停止增加right,同時不斷增加left縮小窗口,直到窗口中字符串不再符合要求,同時每增加一次left更新一輪結果
4,重複2-4直到right到達字符串S的勁頭。
滑窗編程範式:
// 滑窗思想解決字符串子串問題
int left = 0, right = 0;
while (right < s.size()) {
window.add(s[right]);//滑動右邊界
right++;
while (valid) { //滿足條件,滑動左邊界,
window.remove(s[left]);
left++;
}
}
力扣76:最小覆蓋子串
代碼實現:
class Solution {
public:
string minWindow(string s, string t) {
int start = 0,minLen = INT_MAX;
int left = 0,right = 0;
unordered_map<char,int>window;//統計窗內需要匹配的字母和頻次
unordered_map<char,int>needs;//統計需要匹配的字母和頻次
for(auto c:t)
needs[c]++;
int matchs = 0;//統計字母匹配結果,如window有5個g,needs有5個g則g匹配
while(right<s.size())
{
char c1 = s[right];
if(needs.count(c1))
{
window[c1]++;
if(window[c1] == needs[c1])
matchs++;
}
right++;
while(matchs == needs.size())
{
if(right - left<minLen)
{
minLen = right - left;
start = left;
}
char c2 = s[left];
if(needs.count(c2)){
window[c2]--;
if(window[c2] < needs[c2])
matchs--;
}
left++;
}
}
return minLen == INT_MAX? "":s.substr(start,minLen);
}
};
測試結果:
力扣438:找字符串中所有異位詞
代碼實現:
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int>result;
int left = 0, right = 0;
int match = 0;
unordered_map<char, int>needs;//記錄需要異位的字符和頻次
unordered_map<char, int>window;//記錄窗裏面需要異位的字符及頻次
for (auto c : p)
needs[c]++;
while (right < s.size())
{
char c1 = s[right];
if (needs.count(c1))//判斷是不是需要異位的字母,進行窗記錄
{
window[c1]++;
if (window[c1] == needs[c1])
{
match++;
}
}
right++;
while (match == needs.size())
{
if (right - left == p.size())//字母匹配後判斷長度匹配,否則可能窗內有多餘非異位字母
{
result.push_back(left);
}
char c2 = s[left];
if (needs.count(c2))//判斷移除窗外的左邊界是否異位詞,更新window
{
window[c2]--;
if (window[c2]<needs[c2])
match--;
}
left++;
}
}
return result;
}
};
測試結果:
力扣3:無重複最長子串:
代碼實現:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int>window;
int left = 0, right = 0;
int res = 0;
while (right<s.size())
{
char c1 = s[right];
window[c1]++;
right++;
while (window[c1]>1)//有邊界出現重複,移動左邊界直到不重複爲止;
{
char c2 = s[left];
window[c2]--;
left++;
}
res = max(res, right - left);
}
return res;
}
};
測試結果:
參考: