思路
将'G'看成(-1),'R'看成(+1),要求最长的子串,使得子串中‘G’和‘R'的数量相等,则转化为求两个下标(i)和(j),使得前缀和(sum[j]-sum[i-1]=0),即(sum[j] == sum[i-1])。
开一个(pos)数组记录每个(sum[i])第一次出现的位置,之后对每个位置(i),如果(sum[i])未出现过,则将(sum[i])的位置记为(i),否则说明(sum[i])出现过,更新答案。(为什么记录第一次?保证最长子串!)
注意点
(0)第一次出现的位置为下标(0),这是由于前缀和数组中(sum[0]=0)。
const int N=1e6+10;
char s[N];
int pos[N<<1];
int n;
int main()
{
memset(pos,-1,sizeof pos);
scanf("%s",s+1);
int n=strlen(s+1);
int sum=0,res=0;
pos[0+n]=0;
for(int i=1;i<=n;i++)
{
if(s[i] == 'G') sum--;
else sum++;
if(pos[sum+n] == -1)
pos[sum+n]=i;
else
res=max(res,i-pos[sum+n]);
}
cout<<res<<endl;
//system("pause");
return 0;
}