zoukankan      html  css  js  c++  java
  • 算法复习:滑动窗口

    leedcode 209 长度最小的子数组

    滑动窗口的思想是:

    1、设定前指针和后指针,先向后移动后指针直到满足条件,

    2、然后向后移动前指针判断是否仍满足条件,

    3、如果不满足条件继续向后移动后指针直到满足条件,找出满足条件的最短序列即可。

    class Solution {
    public:
        int minSubArrayLen(int s, vector<int>& nums)
        {
            //先计算部分和
            int *donser,sum=0,size=nums.size();
            donser=new int[size];
            for(int i=0;i<size;i++)
            {
                sum+=nums[i];
                donser[i]=sum;
            }
            //滑动窗
            int up=0,down=1,lable_min=size;
            if(size<=1)
            {
                if(size<1)
                    return 0;
                else if(nums[0]>=s)
                    return 1;
                else
                    return 0;
            }
            if(donser[size-1]<s)
                return 0;
            if(donser[0]>=s)
                return 1;
            while(down<size)
            {
                int sum_now;
                if(up==0)
                    sum_now=donser[down];
                else
                    sum_now=donser[down]-donser[up-1];
                if(sum_now<s)
                {
                    down++;
                    continue;
                }
                if(sum_now>=s)
                {
                    if(down-up+1<lable_min)
                        lable_min=down-up+1;
                    up++;
                }
            }
            return lable_min;
        }
    };
    leedcode 209

    注意特值和边界

     计算局部和可以简化计算

    leedcode  438. 找到字符串中所有字母异位词

    窗口长度固定,滑动比较即可,模式串的顺序不重要因此用了map存模式串,注意map会为key自动排序

    bool cmp(map<char,int>donser,map<char,int>tmp)
    {
        map<char,int>::iterator it1=donser.begin();
        int lable=0;
        for(;it1!=donser.end();it1++)
        {
            if(it1->second==tmp[it1->first])
                continue;
            else
                lable=1;
        }
        if(lable==1)
            return false;
        return true;
    }
    class Solution {
    public:
        vector<int> findAnagrams(string s, string p)
        {
            map<char,int>donser;
            map<char,int>tmp;
            vector<int>result;
            if(s.size()<p.size()||p.size()==0)
                return result;
            for(int i=0;i<p.size();i++)
            {
                donser[p[i]]++;
                tmp[s[i]]++;
            }
            int up=0,down=p.size()-1;
            while(down<s.size())
            {
                if(cmp(donser,tmp)==true)
                {
                    result.push_back(up);
                }
                tmp[s[up]]--;
                up++;
                down++;
                tmp[s[down]]++;
            }
            return result;
        }
    };
    leedcode 438

    leedcode 76. 最小覆盖子串

    此题找最短的覆盖子串,最少要遍历一遍,用map会超时,改用数组记录可以通过,前后指针和前面一样

    bool cmp(int *donser,int *tmp)
    {
        int lable=0;
        for(int i=0;i<255;i++)
        {
            if(donser[i]<=tmp[i])
                continue;
            else
            {
                lable=1;
                break;
            }
        }
        if(lable==1)
            return false;
        return true;
    }
    class Solution {
    public:
        string minWindow(string s, string p)
        {
            int donser[256],tmp[256];
            memset(donser,0,sizeof(donser));
            memset(tmp,0,sizeof(tmp));
            string result;
            if(s.size()<p.size()||p.size()==0)
                return result;
            for(int i=0;i<p.size();i++)
            {
                donser[int(p[i]-0)]++;
                tmp[int(s[i]-0)]++;
            }
            int up=0,down=p.size()-1,length=s.size();
            while(true)
            {
                bool cp=cmp(donser,tmp);
                if(down>=s.size()&&up>=s.size()-p.size()||down-up+1<p.size())
                    break;
                if(cp==true)
                {
                    if(down-up+1<=length)
                    {
                        length=down-up+1;
                        result.assign(s,up,length);
                    }
                    tmp[int(s[up]-0)]--;
                    up++;
                    continue;
                }
                if(cp==false&&down<s.size())
                {
                    down++;
                    tmp[int(s[down]-0)]++;
                    continue;
                }
                if(down>=s.size()&&cp==false)
                    break;
            }
            return result;
        }
    };
    leedcode 76

    leetcode 3. 无重复字符的最长子串

    map存出现的字符位置,start标记当前扫描的头位置,max记录最大长度

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            map<char,int>mmp;
            int start=1;
            int max_len=0;
            if(s.size()<=1)
                return s.size();
            for(int i=0;i<=s.size();i++)
            {
                if(i==s.size())//查询完毕
                {
                    max_len=(i-start>max_len?i-start:max_len);
                    break;
                }
                if(mmp[s[i]]==0||(mmp[s[i]]!=0&&mmp[s[i]]<start))
                //第一次出现 or 可覆盖
                {
                    mmp[s[i]]=i+1;
                }
                else if(mmp[s[i]]!=0&&mmp[s[i]]>=start)
                //不是第一次出现 & 不可覆盖
                {
                    max_len=(i-start>max_len?i-start:max_len);
                    start=mmp[s[i]]+1;//更新start
                    mmp[s[i]]=i+1;//覆盖
                }
            }
            return max_len+1;
        }
    };
    leetcode 3
  • 相关阅读:
    BZOJ 2434: [Noi2011]阿狸的打字机
    BZOJ 3640: JC的小苹果
    BZOJ 1444: [Jsoi2009]有趣的游戏
    BZOJ 4820: [Sdoi2017]硬币游戏
    BZOJ 3670: [Noi2014]动物园
    BZOJ 1009: [HNOI2008]GT考试
    BZOJ 3681: Arietta
    BZOJ 1941: [Sdoi2010]Hide and Seek
    BZOJ 4602: [Sdoi2016]齿轮
    BZOJ 3514: Codechef MARCH14 GERALD07加强版
  • 原文地址:https://www.cnblogs.com/dzzy/p/12249440.html
Copyright © 2011-2022 走看看