滑动窗口

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 };

 

567. 字符串的排列 (滑动窗口)

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. 最小区间

 

posted @ 2020-03-30 23:58  乐乐章  阅读(161)  评论(0编辑  收藏  举报