首先,我们要理解题目意思。特别是“小美想从中选出一个包含字母E数量与字母F数量之差最大的子串”这句话,也就是说你选出来的这个子串可以包含E和F,也可以只包含E,总而言之,E和F的差值最大就行。题目给了一个样例——EFEEF,输出结果是2,我一开始想的是在字符串里选只包含E的连续最大子串不就行了吗,这样一想的话,题目所给样例中只包含E的连续最大子串长度刚好是2,然后我就错了。其实题目所给样例也可以选EFEE这个子串,它的差值也是2。再举个例子——EFEEFEE,显然差值最大的子串是EEFEE,为3。
题目有给提示,把E看成1,F看成-1,那么我们就可以通过求和来求最大值了。
for(int i=0; i<n; i++)
{
char ch;
cin >> ch;
a[i]=(ch=='E'? 1:-1);//把E和F用1和-1表示
}
n代表字符串长度,ch=='E'?1:-1,这个知道叭,当ch=='E'时,把1赋给a[i],否则把-1赋给a[i]
for(int i=0; i<n; i++)
{
sum+=a[i];
sum=max(sum,0);
MAX=max(MAX,sum);
}
再然后,来求差值最大的子串。sum+=a[i],sum和0比较取最大值赋给sum,MAX和sum比较取最大值赋给MAX。可能会有点绕。sum其实求的就是子串中E和F数量的差值,那为什么和0比较呢?当sum<0时,也就是说这个子串中F的数量比E多,这个子串就没有必要留着了,把sum置为0,重新开始一个新的子串。那么MAX的作用应该比较明显了吧,它用来存储差值最大的子串,免得sum置为0后,后面新子串的差值没有原来的某一个子串的差值大。
全部代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{
int n;
int sum=0,MAX=0;
cin>>n;
int a[n];
for(int i=0; i<n; i++)
{
char ch;
cin >> ch;
a[i]=(ch=='E'? 1:-1);//把E和F用1和-1表示
}
for(int i=0; i<n; i++)
{
sum+=a[i];
sum=max(sum,0);
MAX=max(MAX,sum);
}
cout<<MAX;
return 0;
}