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

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

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

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

    第一种解法就是暴力解法,采用双循环来遍历所有的子数组,代码如下

    #include<iostream>
    
    using namespace std;
    
    int GetSubArrayLen(int* Arr,int ArrLen,int Val);
    
    int main(void)
    {
        int* Array;
        int ArrLen;
    
        cin >> ArrLen;
        Array = new int[ArrLen];
        for (int i = 0; i < ArrLen; ++i)
            cin >> Array[i];
        int Val;
        cin >> Val;
    
        cout << GetSubArrayLen(Array, ArrLen, Val)<<endl;
        system("pause");
        return 0;
    }
    
    int GetSubArrayLen(int* Arr,int ArrLen,int Val)
    {
        int Len = 0;
        int sum = 0;
        for (int t = 0; t < ArrLen; ++t)
            sum += Arr[t];
        if (sum > Val)
            Len = ArrLen;
        else
            return 0;
    
        for(int i=0;i<ArrLen;++i)
            for (int j = ArrLen - 1; j > i; --j)
            {
                sum = 0;
                for (int t = i; t <= j; ++t)
                    sum += Arr[t];
                if(sum>=Val&&((j-i+1)<=ArrLen))
                    Len=j-i+1;
            }
        return Len;
    }

    这种方法的时间复杂度为O(n^3),可以将数组中每个元素的值替换为前面所有数组的和,比如将arr[3]的值变为arr[0]+arr[1]+arr[2]+arr[3],这样求解一段子数组的和时,比如求2~4的子数组之和,就用修改后的arr[4]-arr[2]就可以了,这样可以省去双循环中循环求和步骤门将时间复杂度降到O(n^2)

    还有一种滑动窗口方法

    连个指针L和R,L表示滑窗的左边框,R表示滑窗的右边框

    左边框向右滑动使窗口变小,右边框向右滑动使窗口变大,开始左右边框是重合在一起的,窗口的和就是重合点所在的数

    1,先将R向右滑动,当和恰好>=s时,记录下滑窗的子数组长度,如果这个长度小于原来的长度,就更新子数组长度

    2,L向右滑动,判断是否仍然>=s,如果满足条件就继续向右滑动

    3,如果<s则将R向右滑动,重复1

    代码如下

    #include<iostream>
    
    using namespace std;
    
    int GetSubArrayLen(int* Arr,int ArrLen,int Val);
    int WindowValue(int* Arr, int L, int R);
    
    int main(void)
    {
        int* Array;
        int ArrLen;
    
        cin >> ArrLen;
        Array = new int[ArrLen];
        for (int i = 0; i < ArrLen; ++i)
            cin >> Array[i];
        int Val;
        cin >> Val;
    
        cout << GetSubArrayLen(Array, ArrLen, Val)<<endl;
        system("pause");
        return 0;
    }
    
    int GetSubArrayLen(int* Arr,int ArrLen,int Val)
    {
        int Len = 0;
        int sum = 0;
        for (int t = 0; t < ArrLen; ++t)
            sum += Arr[t];
        if (sum > Val)
            Len = ArrLen;
        else
            return 0;
    
        int TempLen = 0;
        int L = 0, R = 0;
        while (R < ArrLen)
        {
            while ((WindowValue(Arr, L, R) < Val)&&(R<ArrLen))
                R++;
            while ((WindowValue(Arr, L, R) >= Val)&&(L<=R))
            {
                TempLen = R - L + 1;
                if (TempLen <= Len)
                    Len = TempLen;
                L++;
            }
        }
        return Len;
    }
    
    int WindowValue(int* Arr, int L, int R)
    {
        int Sum = 0;
        for (int i = L; i < R + 1; ++i)
            Sum += Arr[i];
        return Sum;
    }
  • 相关阅读:
    MyBatis中#{}和${}的区别
    springBoot 配置详解
    模板方法模式
    记录一次linux挂载数据盘
    缓存击穿,缓存穿透,缓存雪崩
    Echart折线值相加问题
    mybatis plus主键生成策略
    BigDecimal精度损失
    cent0s6安装nginx小程序https
    Centos6 java运行环境部署
  • 原文地址:https://www.cnblogs.com/wangtianning1223/p/13812240.html
Copyright © 2011-2022 走看看