b_51_最长01相等串长度(map记录相同前缀和出现位置,0特殊处理)
给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等。
思路:map记录相同前缀和数值相同的位置,但没能一次写对,下面是错的程序
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5;
int f[N];
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
string str; cin>>str;
int n=str.size(), ans=0;
unordered_map<int, int> mp;
for (int i=1; i<=n; i++) {
if (str[i-1]=='1') f[i]=f[i-1]+1;
else f[i]=f[i-1]-1;
if (mp.count(f[i])) {
ans=max(ans, i-mp[f[i]]);
}
mp[f[i]]=i;
// cout<<f[i]<<' ';
}
cout<<ans;
return 0;
}
发现f[i]==0时和f[i]有相同值时的处理逻辑是不一样的,比如
输入:10101100
前缀和:1 0 1 0 1 2 1 0 1
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5;
int f[N];
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
string str; cin>>str;
int n=str.size(), ans=0;
unordered_map<int, int> mp;
for (int i=1; i<=n; i++) {
if (str[i-1]=='1') f[i]=f[i-1]+1;
else f[i]=f[i-1]-1;
if (f[i]==0) {
ans=max(ans,i);
} else {
if (mp.find(f[i])!=mp.end()) ans=max(ans, i-mp[f[i]]);
else mp[f[i]]=i; //以及前缀和数值出现过一次就不在记录了
}
}
cout<<ans;
return 0;
}