【算法专题】滑动窗口类

                                个人主页:CSDN_小八哥向前冲~

                                 所属专栏:算法基础入门


目录

长度最小的子数组

无重复字符的最长子串

最大连续1的个数

将x减到0的最小操作数

水果成篮

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

最小覆盖字串


长度最小的子数组

题目:【LeetCode】长度最小的子数组

思路:

解法一:暴力枚举,注意,一般不推荐,因为有些题目因为时间效率问题,过不了  oj   !!!

代码:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n=nums.size(),len=INT_MAX;
        for(int i=0;i<n;i++)
        {
            int sum=0;
            for(int j=i;j<n;j++)
            {
                sum+=nums[j];
                if(sum>=target) len=min(len,j-i+1);
            }
        }
        return len==INT_MAX?0:len;
    }
};

解法二:双指针(滑动窗口)

代码:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
         int sum=0,n=nums.size(),len=INT_MAX;
         for(int left=0,right=0;right<n;right++)
         {
            //进窗口
            sum+=nums[right];
            while(sum>=target)
            {
                len=min(len,right-left+1);
                //出窗口
                sum-=nums[left++];
            }
         }
         return len==INT_MAX?0:len;
    }
};

无重复字符的最长子串

题目:【LeetCode】无重复字符的最长字串

思路:

代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int hash[128]={0};
        int n=s.size(),len=0;
        for(int left=0,right=0;right<n;right++)
        {
            hash[s[right]]++;
            while(hash[s[right]]>1)
                hash[s[left++]]--;
            len=max(len,right-left+1);
        }
        return len;
    }
};

最大连续1的个数

题目:【LeetCode】最大连续1的个数

思路:

代码:

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int n=nums.size(),len=0;
        for(int left=0,right=0,zero=0;right<n;right++)
        {
            if(nums[right]==0)
                zero++;
            while(zero>k)
            {
                if(nums[left++]==0)
                      zero--;
            }
            len=max(len,right-left+1);
        }
        return len;
    }
};

将x减到0的最小操作数

题目:【LeetCode】将x减到0的最小操作数

思路:

如果直接按照题目说的操作,比较难,不好写代码也不好操作,所以我们可以转化成:

在这个数组里面找最大等于某个数的字串。

代码:

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int sum1=0;
        for(auto& e:nums)
            sum1+=e;
        int n=nums.size(),target=sum1-x,ret=-1;
        //细节
        if(target<0)
            return -1;
        for(int left=0,right=0,sum2=0;right<n;right++)
        {
            sum2+=nums[right];//进窗口
            while(sum2>target)
                sum2-=nums[left++];//出窗口
            if(sum2==target)
            {
                ret=max(ret,right-left+1);
            }
        }
        return ret==-1?ret:n-ret;
    }
};

水果成篮

题目:【LeetCode】水果成篮

思路:

代码:

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        int hash[100000]={0};
        int n=fruits.size(),ret=0;
        for(int left=0,right=0,count=0;right<n;right++)
        {
            if(hash[fruits[right]]==0) count++;//记录有效数字
            hash[fruits[right]]++;//进哈希
            while(count>2) //出窗口挪动数据
            {
                hash[fruits[left]]--;
                if(hash[fruits[left]]==0) count--;
                left++;
            }
            ret=max(ret,right-left+1);//更新数据
        }
        return ret;
    }
};

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

题目:【LeetCode】找到字符串中所有字母异位词

思路:

代码:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ret;
        int hash1[26]={0};//哈希记录p的
        for(auto& e:p)
            hash1[e-'a']++;
        int len=p.size();
        int hash2[26]={0};
        int n=s.size(),count=0;//count记录有效字母
        for(int left=0,right=0;right<n;right++)
        {
            char in=s[right];
            if(++hash2[in-'a']<=hash1[in-'a']) count++;//进窗口记录count
            if(right-left+1>len)//出窗口
            {
                char out=s[left++];
                if(hash2[out-'a']--<=hash1[out-'a']) count--;
            }
            if(count==len) ret.push_back(left);//记录下标
        }
        return ret;
    }
};

最小覆盖字串

题目:【LeetCode】最小覆盖字串

思路:

代码:

class Solution {
public:
    string minWindow(string s, string t) {
        int hash1[128]={0};
        int kinds=0;
        for(auto& e:t)
            if(hash1[e]++==0) kinds++;
        int hash2[128]={0};
        int minlen=INT_MAX,begin=-1;
        for(int left=0,right=0,count=0;right<s.size();right++)
        {
            char in=s[right];
            if(++hash2[in]==hash1[in]) count++;
            while(count==kinds)
            {
                if(right-left+1<minlen)
                {
                    minlen=right-left+1;
                    begin=left;
                }
                char out=s[left++];
                if(hash2[out]--==hash1[out]) count--;
            }
        }
       if(begin==-1) return "";
       else return s.substr(begin,minlen);
    }
};

这些题目你都会了嘛?我们下期见!

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
时间序列分段线性表示的滑动窗口算法是一种简易的算法,其主要思想是将时间序列分成多个段落,并用每个段落的平均值来表示整个段落的趋势。这种算法的基本步骤如下: 1. 首先确定一个阈值R,该阈值表示要将时间序列分成多少个段落。 2. 然后计算窗口的长度L,方法是将时间序列的长度除以阈值R,得到的结果即为窗口的长度L。 3. 从时间序列的第一点开始,取前L-1个点作为第一个段落,并用这些点的平均值来表示。 4. 接下来,依次移动窗口,每次移动一个点,取新窗口的前L-1个点作为下一个段落,并用平均值表示。 5. 重复上述步骤,直到遍历完整个时间序列为止。 需要注意的是,这种滑动窗口算法是一种粗略的近似方法,拟合结果可能不够精确,但它是时间序列分段研究中最早的成果之一。 为了选择合适的算法,研究人员通常会浏览大量的论文和教材,并对其中的算法进行仔细阅读和编程实现。同时,为了直观地观察分段效果,还会制作简易的曲线图来展示原始序列和分段序列。这种工作可能会耗费较多的时间和精力,但目的是为了选择最适合的算法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [时间序列专题之三 时间序列的分段线性表示](https://blog.csdn.net/weixin_30347335/article/details/96031376)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值