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;
}
原文地址:https://www.cnblogs.com/wdt1/p/13854341.html