zoukankan      html  css  js  c++  java
  • 16 和至少为 K 的最短子数组(862)

    作者: Turbo时间限制: 1S章节: DS:队列

    晚于: 2020-07-15 12:00:00后提交分数乘系数50%

    截止日期: 2020-07-22 12:00:00

    问题描述 :

    返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。

    如果没有和至少为 K 的非空子数组,返回 -1 。

    示例 1:

    输入:A = [1], K = 1

    输出:1

    示例 2:

    输入:A = [1,2], K = 4

    输出:-1

    示例 3:

    输入:A = [2,-1,2], K = 3

    输出:3

    说明:

    1 <= A.length <= 50000

    -10 ^ 5 <= A[i] <= 10 ^ 5

    1 <= K <= 10 ^ 9

    可参考以下main函数:

    int main()

    {

        vector<int> A;

        int n,data,k;

        cin>>n;

        for(int i=0; i<n; i++)

        {

            cin>>data;

            A.push_back(data);

        }

        cin>>k;

        int result=Solution().shortestSubarray(A,k);

        cout<<result<<endl;

        return 0;

    }

    输入说明 :

    首先输入A数组元素的数目n

    然后输入n个整数

    最后输入k

    输出说明 :

    输出一个整数,表示结果

    输入范例 :

    3
    2 -1 2
    3

    输出范例;

    3
    #include <iostream>
    #include <vector>
    #include <queue>
    using namespace std;
    
    //使用单调的双端队列 从队头到队尾是递增的
        //首先计算前缀和sum[i+1]
        //我们要找的是sum[x2]-sum[x1]>=k 且 x2-x1最小
        //每次入队时 先比较队尾元素是否比自己大 如果比自己大就将队尾元素pop
        //然后从队头开始比较与自己比较 若差大于等于k则符合要求 res=min(res,自己的坐标减去队头元素的坐标) 将当前队头pop
    class Solution {
    public:
        int shortestSubarray(vector<int>& A, int K)
        {
            vector<int> presum(A.size()+1,0);
            int i,len=A.size()+1;
            deque<int> Q;//存储下标,按照队内presum升序
            Q.push_back(0);    //边界条件,前缀和为0,下标为0
            for(i=0;i<A.size();i++)
            {
                presum[i+1]=presum[i]+A[i];
                while(!Q.empty()&&presum[Q.back()]>presum[i+1])
                    Q.pop_back();
                while(!Q.empty()&&(presum[i+1]-presum[Q.front()]>=K))
                {
                    len=min(len,i+1-Q.front());
                    Q.pop_front();
                }
                Q.push_back(i);
            }
    
            if(len==A.size()+1)
                return -1;
            else
                return len;
        }
        
    private:
        int min(int a,int b)
        {
            if(a>b)
                return b;
            else
                return a;
        }
    };
    
    int main()
    {
        vector<int> A;
        int n,data,k;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>data;
            A.push_back(data);
        }
        cin>>k;
        int result=Solution().shortestSubarray(A,k);
        cout<<result<<endl;
        return 0;
    }
    
    //https://blog.csdn.net/qq_21201267/article/details/105662545?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight
  • 相关阅读:
    内存管理
    git学习思维导图
    shell编程 条件判断式----利用 case ..... esac 判断
    shell编程 条件判断式----利用 if .... then ----多重
    shell编程 Shell script 的默认变量($0, $1...)
    VxWorks实验六 基于优先级的抢占式调度及实验的源程序和实验步骤
    Linux下FTP用户的使用配置
    Linux 下 FTP虚拟用户的使用配置
    Linux 常用命令
    实验一 用户界面与Shell命令
  • 原文地址:https://www.cnblogs.com/zmmm/p/13620066.html
Copyright © 2011-2022 走看看