求数组中等于给定值的最长子数组
//数组中等于给定值的最长子数组 #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; }