[玩转算法]滑动窗口

来源:互联网 发布:php极光推送原理 编辑:程序博客网 时间:2024/05/01 11:26

209.Minimum Size Subarray Sum

给定一个整型数组和一个数字s,找到数组中最短的一个连续子数组使得连续子数组的数字和sum >= s,返回这个最短的连续子数组的返回值。

·如,给定数组[2,3,1,2,4,3],s = 7

·答案为[4,3],返回2

暴力解:遍历所有的连续子数组[i,j]

计算其和sum,验证sum=s;

时间复杂度O(n^3)

什么方法时间复杂度可以优化为O(n^2)

 

#include <iostream>#include <vector>#include <cassert>using namespace std;class Solution{public:    //时间复杂度:O(n)    //空间复杂度:O(1)    int minSubArrayLen(int s,vector<int>& nums){        int l = 0;        int r = -1;  //nums[l...r]为滑动窗口        int sum = 0;        int res = nums.size() + 1;        while(l < nums.size() ){            if(r + 1 < nums.size() && sum < s){                r++;                sum += nums[r];            }            else{                 sum -= nums[l++];            }            if(sum >= s){                res = min(res,r-l+1);            }        }        if(res == nums.size() + 1){            return 0;        }        return res;    }    };int main(){    int arr[] = {4,2,4,6,8,9,10};    vector<int> vec(arr,arr+sizeof(arr)/sizeof(int));    int ret = Solution().minSubArrayLen(12,vec);    cout << ret << endl;    return 0;}

 

3.Longest Substring  Without Repeating Characters

在一个字符串中寻找没有重复字母的最长字串

·如“abcabcbb”,则结果为“abc”

·如“bbbb”则结果为’b’

·如“pwwkew”,则结果为“wrk”

 

#include <iostream>#include <vector>#include <string>#include <cassert>using namespace std;class Solution{public:    int lengthOfLongestSubstring(string s){        int freq[256] = {0};        int l = 0;        int r = -1; //滑动窗口为s[l...r]        int res;        while(l < s.size()){            if(r+1 < s.size() && freq[s[r+1]] == 0){                r++;                freq[s[r]]++;            }            else{                freq[s[l++]]--;            }            res = max(res, r-l+1);        }        return res;    }    };int main(){    string arr = "abcabcd";    int ret = Solution().lengthOfLongestSubstring(arr);    cout << ret << endl;    return 0;}

438.Find All Anagrams in a String

给定一个字符串s和一个非空字符串p,找出P中的所有是s的anagrams字符串的子串,返回这些子串的起始索引。

·如s = “cbaebabacd”p = “abc” 返回[0,6]

·如s=”abab”,p = “ba”,返回[0,1,2]

--字符集范围?英文小写字母

--返回的解的顺序?任意

 

#include <iostream>#include <vector>#include <cassert>#include <string>using namespace std;class Solution{public:    vector<int> findAnagramsstring(string nums,string target){        assert(nums.size() > target.size());        vector<int> sv(26,0);        vector<int> pv(26,0);        vector<int> res;        for(int i = 0; i < target.size(); i++){            ++pv[target[i] - 'a'];            ++sv[nums[i] - 'a'];        }        if(sv == pv) res.push_back(0);        for(int i = target.size(); i < nums.size();i++){            ++sv[nums[i] - 'a'];            --sv[nums[i - target.size()] - 'a'];            if(pv == sv) res.push_back(i - target.size() + 1);        }        return res;    }    };int main(){    string nums = "cbaebabacdcba";    string target = "cba";    vector<int> vec = Solution().findAnagramsstring(nums,target);    for(int i = 0; i < vec.size(); i++){        cout << vec[i] << " ";    }    cout << endl;    return 0;}

 

76.Minimum Window Substring

给定一个字符串S和T,在S中寻找最短的子串,包含T中的所有的字符

·如S=”ADOBECODEBANC”; T = “ABC”

·结果为“BANC”

--字符范围?

--若没有解?返回“”

--若有多个解?  保证只有一个解

--什么叫包含所有字符?S=”a”,T = “a”;

 

#include <iostream>#include <vector>#include <cassert>#include <string>using namespace std;class Solution{public:    string MinWinSubstring(string src,string T){        vector<int> Sv(256,0);        vector<int> Tv(256,0);        int lp = -1;        int rp = -1;        int answer = 0x7fffffff;        int begin = 0;        int lack = T.size();        for(int i = 0; i < T.size(); i++){            Tv[T[i]]++;        }                for(int end = 0; end < src.size(); end++){            if(Sv[src[end]] < Tv[src[end]]){                lack--;            }            Sv[src[end]]++;            if(lack == 0){                while(begin < end && Sv[src[begin]] > Tv[src[begin]]){                    Sv[src[begin]]--;                    begin++;                }                if(answer > end - begin + 1){                    answer = end-begin+1;                    lp = begin;                    rp = end;                }                while(lack == 0){                    Sv[src[begin]]--;                    begin += 1;                    lack += 1;                }            }        }        return lp == -1 ?" ": src.substr(lp,rp-lp+1);    }    };int main(){    string src = "ADOBECODEBANC";    string T = "ABC";    string ret = Solution().MinWinSubstring(src,T);    cout << ret << endl;    return 0;}

原创粉丝点击