题目大意:
有一个长度为n的由0和1组成的字符串,找一个最长的子串,使子串中0和1的数量相同。
思路:
用前缀和数组统计1和0的个数,遍历字符串,如果遇到1,则前缀和数组+1,如果遇到0,则-1。建立好前缀和数组后,再遍历数组,如果当前位置的前缀和在前面没有出现过,就记录这个位置,如果当前位置的前缀和不是第一次出现,那么当前的位置减去之前记录的的位置就是对应合法子串的长度,维护最大值即可。
#include<bits/stdc++.h>
using namespace std;
char s[1000005];
int first[2000010], sum[1000005];
int main()
{
int len;
memset(s, 0, sizeof(s));
int out = 0;
sum[0] = 0;
cin >> len >> s + 1;
for (int i = 1; i <= len; i++)
{
sum[i] = sum[i - 1] + (s[i] == '1' ? 1 : -1);//遇到1+1,遇到0-1
}
for (int i = 1; i <= len; i++)
{
if (sum[i] == 0)
{
out = i;
}//如果前缀和等于0,说明从字符串开始到这个位置都是合法的
else if (first[sum[i] + len] != 0 )
{
out = max(out, i - first[sum[i] + len]);
}
else
{
first[sum[i] + len] = i;
}
}
cout << out;
return 0;
}