这道题真是**的一批(自己真是*的一批)
----------------------------------------------
codeforces873B/2019牛客暑期多校第三场签到题B/经典面试题
-----------------------------------------------------------------------------
o(n^2) **都能想出来。
o(n)题解:
1 2 3 4 //索引
0 0 1 1 //主串
-1 -1 1 1 //操作一下
-1 -2 -1 0 //求前缀和
所以 0变-1是为了求前缀和时显然(找规律)看出若我 第四行 出现两个相同的前缀和 则这个区间中一定有01相等子串,直接索引一减,维护最大ans,需注意若前缀和为0,则直接这个区间就是01相等子串 索引就是子串长度。
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
int n;
string s;
int sum[maxn],a[maxn];
map<int,int>ma;
int main(){
cin>>n; cin>>s;
for(int i=0;i<n;i++){
if(s[i]=='0') a[i]=-1;
else a[i]=1;
}
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i-1];
int ans=0;
for(int i=1;i<=n;i++){
if(!ma.count(sum[i])) ma[sum[i]]=i;//每次都保存第一次出现的
if(sum[i]==0) ans=max(ans,i);
else ans=max(ans,i-ma[sum[i]]);
}
cout<<ans<<endl;
return 0;
}
牛客多校还有一问,是求最长子序列使01子序列最长(不改变顺序情况下,可删除0.1)
直接扫一遍,abs(所有0的个数-所有1的个数) tmp=n-ans(na-nb); n是主串长度