zoukankan      html  css  js  c++  java
  • 小于等于给定值的最长子数组

      求数组中等于给定值的最长子数组

    //数组中等于给定值的最长子数组
    #include <iostream>
    #include <map>
    #include <vector>
    using namespace std;
    
    int longest_sum_sub(const vector<int> &a,const int &aim)
    {
        if(a.empty()||a.size()==0)
            return -1;
            
        map<int,int> map;//sum,pos;
        map.insert({0,-1});
        int maxLen=0;
        int curSum=0;
        for(int i=0;i<a.size();++i)
        {
            curSum+=a[i];
            if(map.find(curSum-aim)!=map.end())
                maxLen=max(maxLen,i-map.find(curSum-aim)->second);
            if(map.count(curSum)==0)
                map.insert({curSum,i});
        }
        return maxLen;
    }
    
    int main()
    {
        vector<int> a{6,1,3,2,-1,1,5};
        cout<<longest_sum_sub(a,6)<<endl;
        return 0;
    }

    拓展一

      一个数组中既有奇数又有偶数,求奇数和偶数个数相等的最长的子数组

      将奇数记为-1,偶数记为1,题目转换为求数组中等于0的最长子数组

    //一个数组中既有奇数又有偶数,求奇数和偶数个数相等的最长的子数组
    #include <iostream>
    #include <map>
    #include <vector>
    using namespace std;
    
    int odd_and_even_equal_num(const vector<int> &a)
    {
        if(a.empty()||a.size()==0)
            return -1;
            
        int curSum=0;
        int maxLen=0;
        map<int,int> map;
        map.insert({0,-1});
        vector<int> temp(a.begin(),a.end());
        for(int i=0;i<temp.size();++i)
        {
            if((temp[i]&1)==1)
                temp[i]=-1;
            else
                temp[i]=1;
        }
    
        for(int i=0;i<temp.size();++i)
        {
            curSum+=temp.at(i);
            if(map.count(curSum)!=0)
                maxLen=max(maxLen,i-map.find(curSum)->second);
        
            if(map.count(curSum)==0) 
                map.insert({curSum,i});
        }
        return maxLen;
    }
    int main()
    {
        vector<int> a{6,8,2,6};
        cout<<odd_and_even_equal_num(a)<<endl;
        return 0;
    }

     拓展二

    #include <iostream>
    #include <vector>
    using namespace std;
    
    //都是正数的数组中,小于等于给定值的子数组的最大长度
    int max_len(const vector<int> &a,const int &aim)
    {
        if(a.empty()||a.size()<0)
            return -1;
        int L=0,R=0;
        int len=0;
        int sum=a.at(0);
        while(R<a.size())
        {
            if(sum==aim)
            {
                len=max(len,R-L+1);
                sum-=a.at(L++);
            }
            else if(sum<aim)
            {
                ++R;
                if(R>=a.size())
                    break;
                sum+=a.at(R);
            }
            else
                sum-=a.at(L++);
        }
        return len;
    }
    //有正有负的数组中,小于等于给定值的最大子数组长度
    int max_len_pro(const vector<int>& a, const int& aim)
    {
        if(a.empty()||a.size()<0)
            return -1;
        vector<int> sums(a.size(),0);//从后向前计算,最小累加和数组
        vector<int> ends(a.size(),0);//与sums对应的最小累加和的右边界的下标
        sums.at(a.size()-1)=a.at(a.size()-1);
        ends.at(a.size()-1)=a.size()-1;
    
        //生成sums和ends数组信息
        for(int i=a.size()-2;i>=0;--i)
        {
            if(sums.at(i+1)<0)
            {
                sums.at(i)=a.at(i)+sums.at(i+1);
                ends.at(i)=ends.at(i+1);
            }
            else
            {
                sums.at(i)=a.at(i);
                ends.at(i)=i;
            }
        }
    
        int R=0;//下一个即将要算进来的块的开头
        int sum=0;
        int res_len=0;
        for(int i=0;i<a.size();++i)
        {
            while(R<a.size()&&sum+sums.at(R)<=aim)
            {
                sum+=sums.at(R);
                R=ends.at(R)+1;//下一个带扩的位置
            }
            //向右扩不动
            sum-=R>i?a.at(i):0;
            res_len=max(res_len,R-i);
            R=max(R,i+1);
        }
        return res_len;
    }
    
    int main()
    {
        vector<int> a{1,2,3,6,2,4};
        cout<<max_len(a,6)<<endl;
        cout<<max_len_pro(a,6)<<endl;
        return 0;
    }
  • 相关阅读:
    react-project(二)
    JS--轻松设置获取表单数据
    C#基础---Queue(队列)的应用
    C#基础---Attribute(标签) 和 reflect(反射) 应用二
    C#基础---Attribute(标签) 和 reflect(反射) 应用
    基于Cordova的博客园三方App
    Vue站点的搭建之旅
    移动端浏览器问题汇总
    C#基础---浅谈XML读取以及简单的ORM实现
    WebSite---前台系统图片验证码心得
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10555803.html
Copyright © 2011-2022 走看看