对于字符串1101011
下标 0 1 2 3 4 5 6 7 8
s 1 1 0 1 0 1 1 1
a 0 1 1 -1 1 -1 1 1 1
sum 0 1 2 1 2 1 2 3 4
区间[i,j]的0和1个数相等,sum的i-1和j的值相等,标记第一次出现的位置,找出它最大的间隔距离就行了
0的位置标记为0,这很重要。因为要判断i-1的值
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<queue>
#include<map>
using namespace std;
map<int,int>mp;
int a[100005],sum[100005];
char s[100005];
int main()
{
int len,i,j,ans;
while(scanf("%d",&len)==1)
{
mp.clear();
ans=0;
scanf("%s",s);
for(i=0;i<len;i++)
{
if(s[i]=='0')a[i+1]=-1;
else a[i+1]=1;//从1开始
}
sum[0]=0;
for(i=1;i<=len;i++)
sum[i]=sum[i-1]+a[i];
mp[0]=0;//0的位置必须标记,因为要比较i-1的位置
//map的值是第一次出现的位置
for(i=1;i<=len;i++)
{
if(!mp.count(sum[i]))mp[sum[i]]=i;//没有出现过
else
{
if(ans<i-mp[sum[i]])ans=i-mp[sum[i]];
//减去前缀和第一次出现的位置
}
}
printf("%d\n",ans);
}
return 0;
}