Leetcode上有几道典型的滑动窗口的问题,笔者”labuladong”总结了几行代码的框架,很受益。

    打油诗

    滑动窗口问题 - 图1
    滑动窗口解题逻辑框架:

    1. /* 滑动窗口算法框架 */
    2. void slidingWindow(string s, string t) {
    3. unordered_map<char, int> need, window;
    4. for (char c : t) need[c]++;
    5. int left = 0, right = 0;
    6. int valid = 0;
    7. while (right < s.size()) {
    8. // c 是将移入窗口的字符
    9. char c = s[right];
    10. // 右移窗口
    11. right++;
    12. // 进行窗口内数据的一系列更新
    13. ...
    14. /*** debug 输出的位置 ***/
    15. printf("window: [%d, %d)\n", left, right);
    16. /********************/
    17. // 判断左侧窗口是否要收缩
    18. while (window needs shrink) {
    19. // d 是将移出窗口的字符
    20. char d = s[left];
    21. // 左移窗口
    22. left++;
    23. // 进行窗口内数据的一系列更新
    24. ...
    25. }
    26. }
    27. }

    • LeetCode 76,Minimum Window Substring, Hard,中低频

    滑动窗口问题 - 图2

    1. string minWindow(string s, string t) {
    2. unordered_map<char,int> need;
    3. unordered_map<char,int> window;
    4. for(auto c:t){
    5. need[c]++;
    6. }
    7. int left=0;
    8. int right=0;
    9. int valid=0;
    10. string ret;
    11. int len=s.length();
    12. while(right<s.length()){
    13. char c=s[right];
    14. right++;
    15. if(need.count(c)!=0){
    16. window[c]++;
    17. if(window[c]==need[c]){
    18. valid++;
    19. }
    20. }
    21. //cout << left << "," << right << "," <<valid << "," <<need.size() << endl;
    22. while(valid==need.size()){
    23. if(right-left<=len){
    24. len=right-left;
    25. ret=s.substr(left,len);
    26. }
    27. char d=s[left];
    28. left++;
    29. if(need.count(d)!=0){
    30. if(need[d]==window[d]){
    31. valid--;
    32. }
    33. window[d]--;
    34. }
    35. }
    36. }
    37. return ret;
    38. }

    • LeetCode 567 ,Permutation in String, Medium

    滑动窗口问题 - 图3

    1. bool checkInclusion(string t, string s) {
    2. unordered_map<char,int> need;
    3. unordered_map<char,int> window;
    4. for(auto c:t){
    5. need[c]++;
    6. }
    7. int left=0;
    8. int right=0;
    9. int valid=0;
    10. while(right<s.length()){
    11. char c=s[right];
    12. right++;
    13. if(need.count(c)!=0){
    14. window[c]++;
    15. if(need[c]==window[c]){
    16. valid++;
    17. }
    18. }
    19. while(valid==need.size()){
    20. if(right-left==t.size()){
    21. return true;
    22. }
    23. char d=s[left];
    24. left++;
    25. if(need.count(d)!=0){
    26. if(need[d]==window[d]){
    27. valid--;
    28. }
    29. window[d]--;
    30. }
    31. }
    32. }
    33. return false;
    34. }

    • LeetCode 438 ,Find All Anagrams in a String, Medium,低频

    滑动窗口问题 - 图4
    这个所谓的字母异位词,就是排列,搞个高端的说法就能糊弄人而已,上一题稍微改改就好。

    1. vector<int> findAnagrams(string s, string t) {
    2. vector<int> ret;
    3. if(s.empty()||t.empty()){
    4. return ret;
    5. }
    6. if(s.length()<t.length()){
    7. return ret;
    8. }
    9. unordered_map<char,int> need;
    10. unordered_map<char,int> window;
    11. for(auto c:t){
    12. need[c]++;
    13. }
    14. int left=0;
    15. int right=0;
    16. int valid=0;
    17. while(right<s.length()){
    18. char c=s[right];
    19. right++;
    20. if(need.count(c)!=0){
    21. window[c]++;
    22. if(need[c]==window[c]){
    23. valid++;
    24. }
    25. }
    26. while(valid==need.size()){
    27. if(right-left==t.size()){
    28. ret.emplace_back(left);
    29. }
    30. char d=s[left];
    31. left++;
    32. if(need.count(d)!=0){
    33. if(need[d]==window[d]){
    34. valid--;
    35. }
    36. window[d]--;
    37. }
    38. }
    39. }
    40. return ret;
    41. }