解题思路1:
- 用0分割数组
- 记录每一段的第一个负号和最后一个负号,以及负号的个数
- 对于每一段,如果负号的个数为偶数则此整段就是长度
- 如果负号的个数为奇数,则比较该段开始到第一个负号的长度a和最后一个负号到结尾的长度b。总长度-min(a,b)就是该段的长度
- 比较每段长度取最大值即可。
#include<bits/stdc++.h>
using namespace std;
struct record{
int start;
int end;
vector<int> n_arr;
};
int main(){
int n;
cin>>n;
vector<int> v(n);
for(int i = 0; i< n;++i){
scanf("%d", &v[i]);
}
vector<record> rcds;
record tmp_rcd;
tmp_rcd.start = -1;
int i;
for(i = 0; i < n; ++i){
if(v[i] != 0){
tmp_rcd.end++;
if(v[i] < 0){
tmp_rcd.n_arr.push_back(i);
}
}
else{
tmp_rcd.end = i;
rcds.push_back(tmp_rcd);
tmp_rcd.start = i;
for(auto j=tmp_rcd.n_arr.begin() ;j != tmp_rcd.n_arr.end();){
tmp_rcd.n_arr.erase(j);
}
}
}
if (v[i - 1] != 0){
tmp_rcd.end = i;
rcds.push_back(tmp_rcd);
}
int max_ln = 0;
for(int i = 0; i < rcds.size(); ++i){
if (rcds[i].n_arr.size() % 2 == 0){
max_ln = max(max_ln, rcds[i].end - rcds[i].start - 1);
}
else{
int tmp_ln = rcds[i].end - rcds[i].start - 1;
tmp_ln = tmp_ln - min(rcds[i].n_arr[0]-rcds[i].start-1, rcds[i].end - rcds[i].n_arr[rcds[i].n_arr.size()-1]-1 ) -1;
max_ln = max(max_ln, tmp_ln);
}
}
cout<<max_ln<<endl;
return 0;
}
解题思路2:
- 数组总长度n,i从1到n,在递推的过程中记录当前状态处最长的非零串的长度。并记录该串的正负号,遇到负数*-1即可。
- 取出记录长度中最大的值为正的长度即可。
- 目测可以空间优化。(尚未做)
#include<bits/stdc++.h>
using namespace std;
int solve2(int n, vector<int> & v, vector<pair<int,int>> &dp);
int main(){
int n;
cin>>n;
vector<int> v(n);
vector<pair<int,int>> dp(n+1,make_pair(INT_MAX, INT_MAX));
for(int i = 0; i < n; ++i){
cin>>v[i];
}
cout<<solve2(n,v,dp)<<endl;
return 0;
}
int solve2(int n, vector<int> & v, vector<pair<int,int>> &dp){
dp[0] = make_pair(0, 0);
dp[1].first = v[0]!=0;
if(v[0]>0) dp[1].second = 1;
else if (v[0]<0) dp[1].second = -1;
else dp[0].second = 0;
int ans = 0;
for(int i = 2; i <= n; ++i){
if (v[i-1] != 0) dp[i].first = dp[i-1].first+1;
else dp[i].first = 0;
if(v[i-1] == 0) dp[i].second = 0;
else{
if(dp[i-1].second == 0){
if(v[i-1]>0) dp[i].second = 1;
else dp[i].second = -1;
}
else {
if (v[i-1]>0) dp[i].second = dp[i-1].second;
else dp[i].second = dp[i-1].second*(-1);
}
}
ans = max(ans,dp[i].first*dp[i].second);
}
return ans;
}