滑动窗口
https://labuladong.gitbook.io/algo/mu-lu-ye/hua-dong-chuang-kou-ji-qiao-jin-jie
滑动窗口题目:
3. 无重复字符的最长子串
class Solution { public: int lengthOfLongestSubstring(string s) { int left = 0; int right = 0; int res = 0; unordered_map<char,int> char_map; while(right < s.size()) { char cur_c = s[right]; char_map[cur_c]++; right++; while(char_map[cur_c]>1) { char cur_c = s[left]; char_map[cur_c]--; left++; } res = max(res,right-left); } return res; } };
30. Substring with Concatenation of All Words (滑动窗口)
1 class Solution { 2 public: 3 vector<int> findSubstring(string s, vector<string>& words) { 4 unordered_map<string,int> need_map; 5 for(auto word: words){ 6 need_map[word]++; 7 } 8 int len = words[0].size(); 9 vector<int> res; 10 // 每次滑动长度为len, 所以要从0,1,,, len 都作为起始位置 滑动一次才能保证所有位置都被遍历到了 11 for (int i = 0; i < len;++i) { 12 // 滑动窗口模板 13 int left = i; 14 int right = i; 15 unordered_map<string,int> window_map; 16 int valid_cnt = 0; 17 while(right < s.size()) { 18 string cur_word = s.substr(right, len); 19 if(need_map.find(cur_word)!=need_map.end()) { 20 window_map[cur_word]++; 21 if(need_map[cur_word] == window_map[cur_word]) { 22 valid_cnt++; 23 } 24 } 25 right+=len; // 注意每次滑动的长度 26 while(right-left>=words.size()*words[0].size()) { 27 string cur_word = s.substr(left,len); 28 if (valid_cnt==need_map.size()) { 29 res.emplace_back(left); 30 } 31 if(need_map.find(cur_word)!=need_map.end()) { 32 if(need_map[cur_word] == window_map[cur_word]) { 33 valid_cnt--; 34 } 35 window_map[cur_word]--; 36 } 37 left+=len;// 注意每次滑动的长度 38 } 39 } 40 } 41 return res; 42 } 43 };
76. Minimum Window Substring(hard 滑动窗口)
1 class Solution { 2 public: 3 string minWindow(string s, string t) { 4 unordered_map<char,int> need_map; 5 unordered_map<char,int> window_map; 6 for(auto c:t) { 7 need_map[c]++; 8 } 9 int left = 0; 10 int right = 0; 11 int valid_cnt = 0;// 符合条件的char计数 12 int res_start = 0; 13 int res_len = INT_MAX; 14 while(right < s.size()) { 15 16 char cur_c = s[right]; 17 // 更新窗口数据 18 if(need_map.find(cur_c) != need_map.end()) { 19 window_map[cur_c]++; 20 if(window_map[cur_c] == need_map[cur_c]) 21 valid_cnt++; 22 } 23 // 窗口扩大 24 right++; 25 26 printf("window: [%d, %d)\n", left, right); 27 28 // 缩减窗口 29 while(valid_cnt == need_map.size()) { // 30 31 // 更新结果 32 if(res_len > right - left) { 33 res_len = right - left; 34 res_start = left; 35 } 36 // 缩减窗口 37 char cur_c = s[left]; 38 left++; 39 40 // 更新窗口数据 41 if (need_map.find(cur_c)!=need_map.end()) { 42 if(window_map[cur_c] == need_map[cur_c]) 43 valid_cnt--; 44 window_map[cur_c]--; 45 } 46 } 47 } 48 return res_len == INT_MAX ? "" : s.substr(res_start, res_len); 49 } 50 };
class Solution { public: vector<int> findAnagrams(string s, string t) { unordered_map<char,int> need_map,window_map; for(char c:t) { need_map[c]++; } int left = 0; int right = 0; int valid = 0; vector<int> res; while(right < s.size()) { char cur_c = s[right]; if(need_map.find(cur_c) != need_map.end()) { window_map[cur_c]++; if(need_map[cur_c] == window_map[cur_c]) { valid++; } } right++; while(right-left>=t.size()) { if (valid == t.size()) { res.emplace_back(left); } char cur_c = s[left]; if(need_map.find(cur_c) != need_map.end()) { if(need_map[cur_c] == window_map[cur_c]) { valid--; } window_map[cur_c]--; } left++; } } return res; } };
438. 找到字符串中所有字母异位词
1 class Solution { 2 public: 3 vector<int> findAnagrams(string s, string t) { 4 unordered_map<char,int> need_map,window_map; 5 for(char c:t) { 6 need_map[c]++; 7 } 8 int left = 0; 9 int right = 0; 10 int valid = 0; 11 vector<int> res; 12 while(right < s.size()) { 13 char cur_c = s[right]; 14 if(need_map.find(cur_c) != need_map.end()) { 15 window_map[cur_c]++; 16 if(need_map[cur_c] == window_map[cur_c]) { 17 valid++; 18 } 19 } 20 right++; 21 cout << left << " " << right << endl; 22 while(right-left>=t.size()) { 23 cout << valid << endl; 24 if (valid == need_map.size()) { 25 res.emplace_back(left); 26 } 27 char cur_c = s[left]; 28 if(need_map.find(cur_c) != need_map.end()) { 29 if(need_map[cur_c] == window_map[cur_c]) { 30 valid--; 31 } 32 window_map[cur_c]--; 33 } 34 left++; 35 } 36 } 37 return res; 38 } 39 };
209. Minimum Size Subarray Sum(双指针)
找出该数组中满足其和 ≥ target
的长度最小的 连续子数组 [numsl,
1 class Solution { 2 public: 3 int minSubArrayLen(int target, vector<int>& nums) { 4 int low = 0; 5 int high = 0; 6 int res = INT_MAX; 7 int sum = 0; 8 while(high < nums.size()) { 9 if (sum <= target) { 10 sum+=nums[high]; 11 high++; 12 } 13 while(sum >= target) { 14 res = min(res,high-low); 15 sum-= nums[low]; 16 low++; 17 } 18 } 19 return res==INT_MAX? 0:res; 20 } 21 };
239. Sliding Window Maximum (滑动窗口最大值, 大根堆)
632. 最小区间